TagHelpers : Authoring Nested TagHelpers in ASP.NET Core MVC

As one of the best new features of ASP.NET Core, TagHelpers simplify the work required to design views that interact with the data model. You can write HTML that not only binds to the data model, but also offers the advantages of HTML and CSS. TagHelpers allow you to provide robust, maintainable, reusable code with information provided on the server. This is the second article in this series covering Authoring TagHelpers. When building complex TagHelpers, it’s best to break down the logic into several TagHelpers that communicate with each other. This communication is handled by the context parameter of the process method. The context parameter has an Items property that holds information for parent and child TagHelpers. Let’s take a simple example of Company and Location, where Location is the child TagHelper of Company. This TagHelper would show the contact details of company. Here’s the sample markup:


<contact name="@Model.Name">  
    <location city="@Model.Location.City" country="@Model.Location.Country" phone="@Model.Location.Phone"></location>  
</contact>  

We consider two model classes:


 public class Company  
    {  
        public string Name { get; set; }  

        private Location _location;  
        public Location Location  
        {  
            get { return \_location ?? (\_location = new Location()); }  
        }  
    }  

    public class Location  
    {  
        public string Country { get; set; }  
        public string City { get; set; }  
        public string Phone { get; set; }  
    }  

The Contact TagHelper class is defined below. Note how the context parameter is used to store the Company object’s information. This Company object is then used by the child TagHelper Location to process location information. The output parameter’s GetChildContentAsync() method helps to get the content of child TagHelper asynchronously.


 public class ContactTagHelper : TagHelper  
    {  
        public string Name  
        {  
            get { return Contact.Name; }  
            set { Contact.Name = value; }  
        }  


        private Company _contact;  
        private Company Contact  
        {  
            get  
            {  
                return \_contact ?? (\_contact = new Company());  
            }  
            set  
            {  
                _contact = value;  
            }  
        }  
        public override async void Process(TagHelperContext context, TagHelperOutput output)  
        {  

            //In taghelper, we can transfer some information to its children taghelpers via context.Items.  
            //The children taghelpers will get a copy of its parent's Items.   

            // here we can save some information. Its children tags can obtain this information.  
            context.Items["Parent"] = Contact;  
            // render the children taghelpers. This is necessary to await since we need location info to render.  
            TagHelperContent locationContent = await output.GetChildContentAsync();  

            var loc = context.Items["Parent"] as Company;  
            StringBuilder sb = new StringBuilder();  
            string str = string.Format(@"


           {0}  

             {2}, {1}  

               Ph:{3}       


", Name, loc.Location.Country,loc.Location.City,loc.Location.Phone);  
            sb.Append(str);  
            output.Content.AppendHtml(sb.ToString());  
            // when we get all the information from children taghelpers,   
            // the we can render the html markup and startup scripts.  
        }  
    }  

The Location TagHelper class is defined below. This child TagHelper gets the information of shared Parent object through the Context.Items collection:


  public class LocationTagHelper : TagHelper  
    {  
        public string Country { get; set; }  
        public string City { get; set; }  
        public string Phone { get; set; }  

        public override void Process(TagHelperContext context, TagHelperOutput output)  
        {  
            // Get the information from its parent tag.  
            var parent = context.Items["Parent"] as Company;  
            // set its attributes' values to some instance from the parent.  
            parent.Location.Country = Country;  
            parent.Location.City = City;  
            parent.Location.Phone = Phone;  
            // save some information so that its children taghelpers can use.  
            context.Items["Parent"] = parent.Location;  
            // render the children taghelpers  
            output.GetChildContentAsync();  


        }  
    }  

The Contact TagHelper is now ready! When we use this on a view page and bind to any model that returns contact name, city, country and phone, it is rendered as below: Rendered TagHelper Rendered TagHelper The rendered markup in browser is as below: Rendered markup Rendered markup ComponentOne Studio MVC Edition controls are compatible with ASP.NET Core and has TagHelpers for all its controls.

View our ASP.NET Core MVC ControlExplorer

GrapeCity

GrapeCity Developer Tools
comments powered by Disqus