Преобразовать IHtmlContent/TagBuilder в строку в C#
Я использую ASP.NET 5. Мне нужно преобразовать IHtmlContent в строку
IIHtmlContent
является частью ASP.NET 5
Microsoft.AspNet.Html.Abstractions
пространство имен и является интерфейсом, который TagBuilder
инвентарь
Упрощенно у меня есть следующий метод
public static IHtmlContent GetContent()
{
return new HtmlString("<tag>blah</tag>");
}
Когда я ссылаюсь на это
string output = GetContent().ToString();
Я получаю следующий вывод для GetContent()
"Microsoft.AspNet.Mvc.Rendering.TagBuilder"
и не
<tag>blah</tag>
который я хочу
Я также пытался использовать StringBuilder
StringBuilder html = new StringBuilder();
html.Append(GetContent());
но он также добавляет то же пространство имен, а не строковое значение
Я пытался привести его к TagBuilder
TagBuilder content = (TagBuilder)GetContent();
но TagBuilder не имеет метода, который преобразует в строку
Как преобразовать IHtmlContent или TagBuilder в строку?
6 ответов
Если все, что вам нужно сделать, это вывести содержимое в виде строки, просто добавьте этот метод и передайте свой объект IHtmlContent в качестве параметра, чтобы получить вывод строки:
public static string GetString(IHtmlContent content)
{
var writer = new System.IO.StringWriter();
content.WriteTo(writer, HtmlEncoder.Default);
return writer.ToString();
}
Возможно, вы захотите пересмотреть, почему вы используете этот подход, так как TagBuilder позволяет использовать практически любой тип пользовательского HTML, о котором вы только можете подумать. Вывод текста вручную, вероятно, не требуется.
Добавление к ответу выше:
Новый экземпляр HtmlEncoder
не работает в ASP.NET Core RTM как Microsoft.Extensions.WebEncoders
пространство имен было удалено и новый HtmlEncoder
класс перемещен в новое пространство имен System.Text.Encodings.Web
, но этот класс теперь написан как абстрактный и запечатанный класс, поэтому вы не можете создать новый экземпляр или производный класс от него.
Проходить HtmlEncoder.Default
к методу и он будет работать
public static string GetString(IHtmlContent content)
{
var writer = new System.IO.StringWriter();
content.WriteTo(writer, HtmlEncoder.Default);
return writer.ToString();
}
На самом деле ASP.NET Core представил несколько тщательных оптимизаций. Если вы создаете метод расширения HTML, то самый эффективный способ - избежать строки:
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;
}
Наконец, с точки зрения бритвы, нам даже не нужно @Html.Raw(Html.GetContent())
больше (что раньше требовалось в ASP.NET MVC 5), просто вызывая @Html.GetContent()
Достаточно, и Razor позаботится обо всем сбегающем бизнесе.
Для ASP.NET core 2.0 код выглядит немного иначе:
public static string GetString(IHtmlContent htmlContent)
{
var writer = new System.IO.StringWriter();
htmlContent.WriteTo(writer, HtmlEncoder.Default);
return writer.ToString();
}
Вот метод расширения, поэтому вы можете использовать его как 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();
}
}
Есть пример: 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();
}
}