Search code examples
c#asp.net-mvcasp.net-corerazorhtml-helper

ASP .NET Core - Extending @Html.EditorFor to append <span>


I am porting an old .NET 4.8 app to .NET Core and the old app has custom code which extends the @Html.EditorFor to wrap the <input> within a and appends a <span> after the <input> tag (basically to add a "%" sign after the input field). I have added the older code below.

public static MvcHtmlString Addon(this MvcHtmlString htmlText, string text, string classes)
{
    var wrapper = new TagBuilder("div");
    wrapper.AddCssClass("input-group");
    wrapper.AddCssClass(classes);
    wrapper.InnerHtml = htmlText.ToHtmlString();
    var span = new TagBuilder("span");
    span.AddCssClass("input-group-addon");
    span.InnerHtml = text;
    wrapper.InnerHtml += span.ToString();

    return new MvcHtmlString(wrapper.ToString());
}

The above code is used in conjunction with the @Html.EditorFor as below.

@Html.EditorFor(model => model.PercentageOfControlledSubstances, new { htmlAttributes = new { @class = "form-control short-textfield percent" } }).**Addon**("%", "med-textfield")

When compiling I get an error stating:

Reference to type 'HtmlString' claims it is defined in 'System.Web', but it could not be found.

Below is a screenshot of what the final rendering should look like.

 tag followed by

I know this is a conversion from .NET 4.8 to .NET Core and I have been searching how to convert my code but cannot find documentation on how to do this in .NET Core. After a lot of searching, it looks like .NET Core uses either IHtmlContent or HtmlHelper(s) but I am unsure - since I can find no documentation.


Solution

  • For .NET Core, you need to migrate from MvcHtmlString which only supports .NET Framework MVC to IHtmlContent.

    The implementation is almost similar, just need to migrate following:

    No .NET Framework MVC .NET Core MVC
    1 HtmlMvcString IHtmlContent
    2 Append HTML with <Tag Builder instance>.InnerHtml += <HTML string> Apend HTML with <Tag Builder instance>.InnerHtml.AppendHtml(<HTML string>)
    3 Retrieve parsed HTML from Html.Editor() with htmlText Retrieve parsed HTML from Html.Editor() by using StringWriter
    4 Return value with MvcHtmlString instance Return value with HtmlString instance
    using Microsoft.AspNetCore.Html;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using System.IO;
    using System.Text.Encodings.Web;
    
    public static class HtmlHelperEditorExtensions
    {
        public static IHtmlContent Addon(this IHtmlContent htmlContent, string text, string classes)
        {
            var wrapper = new TagBuilder("div");
            wrapper.AddCssClass("input-group");
            wrapper.AddCssClass(classes);
    
            using (var writer = new StringWriter())
            {
                htmlContent.WriteTo(writer, HtmlEncoder.Default);
                wrapper.InnerHtml.AppendHtml(writer.ToString());
            }
    
            var span = new TagBuilder("span");
            span.AddCssClass("input-group-addon");
            span.InnerHtml.AppendHtml(text);
    
            wrapper.InnerHtml.AppendHtml(span);
    
            using (var writer = new StringWriter())
            {
                wrapper.WriteTo(writer, HtmlEncoder.Default);
                return new HtmlString(writer.ToString());
            }
        }
    }