Reputation: 2099
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?
Upvotes: 48
Views: 37905
Reputation: 111
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();
}
}
Upvotes: 2
Reputation: 33572
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.
Upvotes: 23
Reputation: 2035
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();
}
}
Upvotes: 67
Reputation: 77
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();
}
}
Upvotes: 0
Reputation: 7512
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();
}
Upvotes: 28