48

I am using ASP.NET 5. I need to convert IHtmlContent to String

IIHtmlContent is part of the ASP.NET 5 Microsoft.AspNet.Html.Abstractions namespace and is an interface that TagBuilder implements

Simplified I have the following method

public static IHtmlContent GetContent()
{
    return new HtmlString("<tag>blah</tag>");
}

When I reference it

string output = GetContent().ToString();

I get the following output for GetContent()

"Microsoft.AspNet.Mvc.Rendering.TagBuilder" 

and not

<tag>blah</tag>

which I want

I also tried using StringBuilder

StringBuilder html = new StringBuilder();
html.Append(GetContent());

but it also appends the same namespace and not the string value

I tried to cast it to TagBuilder

TagBuilder content = (TagBuilder)GetContent();

but TagBuilder doesn't have a method that converts to string

How do I convert IHtmlContent or TagBuilder to a string?

3
  • 1
    What about ToHtmlString? Also, where do you get IHtmlContent from? Commented Nov 12, 2015 at 9:34
  • 1
    I was referring to HtmlString class's method. Can you point me to the documentation for IHtmlContent? It doesn't seem to be on MSDN Commented Nov 12, 2015 at 10:00
  • It's seven years ago, but maybe it's usefull for someone anymore. If you call GetContent() from your html source code file (e.g.: in your cshtml: @Model.GetContent()) then in your browser app you'll see: blah. Therefor contains the question also a piece of an answer. Commented Dec 16, 2022 at 10:55

5 Answers 5

67

If all you need to do is output the contents as a string, just add this method and pass your IHtmlContent object as a parameter to get the string output:

public static string GetString(IHtmlContent content)
{
    using (var writer = new System.IO.StringWriter())
    {        
        content.WriteTo(writer, HtmlEncoder.Default);
        return writer.ToString();
    } 
}     
Sign up to request clarification or add additional context in comments.

6 Comments

Good answer.. This is what I was looking for.
Does not work on asp.vnext core. use HtmlEncoder.Default instead
Shouldn't the StringWriter be wrapped in a using block?
@bradlis7 you are correct. I have updated the solution to reflect your suggestion.
With Razor in Core you can simply use @tagBuilderInstance. It will build and write the result.
|
28

Adding to the answer above:

The new instance of the HtmlEncoder doesn't work in ASP.NET Core RTM as the Microsoft.Extensions.WebEncoders namespace was removed and the new HtmlEncoder class is moved to a new namespace System.Text.Encodings.Web, but this class is now written as an abstract and sealed class so you can't create a new instance or a derived class from it.

Pass HtmlEncoder.Default to the method and it will work

public static string GetString(IHtmlContent content)
{
    var writer = new System.IO.StringWriter();
    content.WriteTo(writer, HtmlEncoder.Default);
    return writer.ToString();
}

Comments

23

ASP.NET Core actually introduced handful of careful optimizations. If you are building an HTML extension method, then the most efficient way is to avoid string:

public static IHtmlContent GetContent(this IHtmlHelper helper)
{
    var content = new HtmlContentBuilder()
                     .AppendHtml("<ol class='content-body'><li>")
                     .AppendHtml(helper.ActionLink("Home", "Index", "Home"))
                     .AppendHtml("</li>");

    if(SomeCondition())
    {
        content.AppendHtml(@"<div>
            Note `HtmlContentBuilder.AppendHtml()` is Mutable
            as well as Fluent/Chainable.
        </div>");
    }

    return content;
}

Finally in the razor view, we don't even need @Html.Raw(Html.GetContent()) anymore (which used to be required in ASP.NET MVC 5) - not valid based on Lukáš Kmoch comment below: ASP.NET MVC 5 has type MvcHtmlString. You don't need to use Html.Raw()

just calling @Html.GetContent() is sufficient and Razor will take care of all the escaping business.

2 Comments

The reason I liked the server side rendering is that it was so much faster to code boring markup at the expense of performance. Why are we injecting an ordered list into markup so we can render and anchor tag? This has to be bad for SEO, and increase development time. Arrrgh
ASP.NET MVC 5 has type MvcHtmlString. You don't need to use Html.Raw()
2

Here's an extension method so you can use it like ToString().

    public static string ToHtmlString(this IHtmlContent content)
    {
        if (content is HtmlString htmlString)
        {
            return htmlString.Value;
        }

        using (var writer = new StringWriter())
        {
            content.WriteTo(writer, HtmlEncoder.Default);
            return writer.ToString();
        }
    }

Comments

0

there is a sample: https://github.com/aspnet/Mvc/blob/release/2.2/test/Microsoft.AspNetCore.Mvc.Views.TestCommon/HtmlContentUtilities.cs

public static string HtmlContentToString(IHtmlContent content, HtmlEncoder encoder = null)
        {
            if (encoder == null)
            {
                encoder = new HtmlTestEncoder();
            }

            using (var writer = new StringWriter())
            {
                content.WriteTo(writer, encoder);
                return writer.ToString();
            }
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.