Search code examples
c#asp.net-mvcasp.net-core-mvchtml-helpertag-helpers

What is the equivalent of @Model.propertyname in ASP Tag Helpers?


In vanilla HTML Helpers, I usually use <div>@Model.Name</div> to print Name property, is there similar function for Tag Helpers?


Solution

  • As I said in my comment, there isn't a standard tag helper that generates a div (or there wasn't last time I looked, anyway). Here's an example of a tag helper that we wrote in my office to generate a div:

    [HtmlTargetElement("div", Attributes = FOR_ATTRIBUTE_NAME)]
    public class DivTagHelper : TagHelper
    {
        private const string FOR_ATTRIBUTE_NAME = "si-for";
    
        /// <summary>
        /// Creates a new <see cref="DivTagHelper"/>.
        /// </summary>
        /// <param name="generator">The <see cref="IHtmlGenerator"/>.</param>
        public DivTagHelper(IHtmlGenerator generator)
        {
            Generator = generator;
        }
    
        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }
    
        protected IHtmlGenerator Generator { get; }
    
        /// <summary>
        /// An expression to be evaluated against the current model.
        /// </summary>
        [HtmlAttributeName(FOR_ATTRIBUTE_NAME)]
        public ModelExpression For { get; set; }
    
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var childContent = output.Content.IsModified ? output.Content.GetContent() :
                (await output.GetChildContentAsync()).GetContent();
    
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
    
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
    
            output.TagName = "div";
    
            string content;
    
            if (For.Metadata.UnderlyingOrModelType == typeof(bool))
            {
                content = ((bool?) For.Model).ToYesNo();
            }
            else
            {
                var displayFormatString = For.ModelExplorer.Metadata.DisplayFormatString;
    
                content = string.IsNullOrEmpty(displayFormatString)
                            ? For.Model?.ToString()
                            : string.Format(displayFormatString, For.Model);
            }
    
            // Honour the model's specified format if there is one.
            output.Content.SetContent(content);
            output.PostContent.SetHtmlContent(childContent);
        }
    }
    

    Here's a usage sample:

    <li class="TypeFile">
        <si-label si-for="FileSize"></si-label>
        <div si-for="FileSize" id="FileSize" class="ReadOnlyValue"></div>
        <input class="subForm" asp-for="FileSizeInBytes" />
    </li>
    

    Note that the "si" prefixes are our company initials to ensure no ambiguity with existing attributes.

    Here's an output sample:

    <li class="TypeFile">
        <label for="FileSize">File Size:</label>
        <div id="FileSize" class="ReadOnlyValue">13.700KB</div>
        <input class="subForm" type="hidden" id="FileSizeInBytes" name="FileSizeInBytes" value="14029" />
    </li>