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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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();
}
}
Method 2
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();
}
Method 3
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 – not valid based on Lukáš Kmoch comment below: @Html.Raw(Html.GetContent()) anymore (which used to be required in ASP.NET MVC 5)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.
Method 4
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();
}
}
Method 5
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();
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0