渲染 Json+Ld 脚本时,ASP.NET Core 不应在 TagBuilder 中编码属性值

Posted

技术标签:

【中文标题】渲染 Json+Ld 脚本时,ASP.NET Core 不应在 TagBuilder 中编码属性值【英文标题】:ASP.NET Core should not encode attribute value in TagBuilder when rendering Json+Ld script 【发布时间】:2022-01-14 05:03:24 【问题描述】:

我写了一个 htmlHelper 扩展来渲染 Json+Ld 脚本标签。 找你帮忙的原因是,type属性值“application/ld+json”被编码,看起来像“application/ld+json”,我找到了解决办法。

我的 HtmlHelper 的 C# 代码:

    public static IHtmlContent GetJsonLdScriptTag(this IHtmlHelper helper, string innerText)
    
        //if(string.IsNullOrEmpty(innerText))
        //    return HtmlString.Empty;

        var tag = new TagBuilder("script");
        tag.MergeAttribute("type", "application/ld+json");

        tag.InnerHtml.AppendHtml(innerText);
        tag.TagRenderMode = TagRenderMode.Normal;

        return tag;
    

在我看来,我使用调用 Html 扩展名:

    @Html.GetJsonLdScriptTag("")

HTML 输出为:

<script type="application/ld&#x2B;json"></script>

我尝试使用 HtmlDecode(...) 并返回 Html.Raw(...); 进行解码,但没有成功。

另一个尝试是返回字符串而不是 IHtmlContent 对象,但这也失败了。

    public static string GetJsonLdScriptTag(this IHtmlHelper helper, string innerText)
    
        //if(string.IsNullOrEmpty(innerText))
        //    return HtmlString.Empty;

        var tag = new TagBuilder("script");
        tag.MergeAttribute("type", "application/ld+json");

        tag.InnerHtml.AppendHtml(innerText);
        tag.TagRenderMode = TagRenderMode.Normal;

        return tag.ToHtmlString();
    

    public static string ToHtmlString(this IHtmlContent content)
    
        using var writer = new IO.StringWriter();
        content.WriteTo(writer, HtmlEncoder.Default);
        return writer.ToString();
    

您是否有想法在不使用 hack 的情况下处理此问题?

最好的蒂诺

【问题讨论】:

【参考方案1】:

查看the source code,似乎没有任何方法可以禁用属性值的编码。可能值得logging an issue 看看是否可以添加;但在短期内,您需要使用 TagBuilder 类以外的其他东西。

private sealed class JsonLdScriptTag : IHtmlContent

    private readonly string _innerText;
    
    public JsonLdScriptTag(string innerText)
    
        _innerText = innerText;
    
    
    public void WriteTo(TextWriter writer, HtmlEncoder encoder)
    
        writer.Write(@"<script type=""application/ld+json"">");
        writer.Write(_innerText);
        writer.Write("</script>");
    


public static IHtmlContent GetJsonLdScriptTag(this IHtmlHelper helper, string innerText)
    => new JsonLdScriptTag(innerText);

【讨论】:

嗨,理查德,非常感谢您的解决方案。效果很好。

以上是关于渲染 Json+Ld 脚本时,ASP.NET Core 不应在 TagBuilder 中编码属性值的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core PartialView 中加载脚本后渲染脚本部分

ASP.NET MVC 返回 Json 结果?

关于ASP.NET MVC部分视图渲染问题。

如何使用Ajax动态更新JSON-LD脚本?

如何将json返回的数据绑定到asp.net中的jquery gridview?

如何在 ASP.NET Core 中基于解决方案配置运行脚本