Преобразовать IHtmlContent/TagBuilder в строку в C#

Я использую ASP.NET 5. Мне нужно преобразовать IHtmlContent в строку

IIHtmlContent является частью ASP.NET 5Microsoft.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();
            }
        }
Другие вопросы по тегам