【问题标题】:How do I write unencoded Json to my View using Razor?如何使用 Razor 将未编码的 Json 写入我的视图?
【发布时间】:2011-05-03 15:11:34
【问题描述】:

我正在尝试使用 Razor 将对象作为 JSON 写入我的 Asp.Net MVC 视图,如下所示:

<script type="text/javascript">
  var potentialAttendees = @Json.Encode(Model.PotentialAttendees);
</script>

问题是在输出中 JSON 被编码,而我的浏览器不喜欢它。例如:

<script type="text/javascript">
    var potentialAttendees = [{&quot;Name&quot;:&quot;Samuel Jack&quot;},];
</script>

如何让 Razor 发出未编码的 JSON?

【问题讨论】:

    标签: asp.net-mvc json razor


    【解决方案1】:

    Newtonsoft 的 JsonConvert.SerializeObject 的行为与 Json.Encode 的行为不同,并且按照 @david-k-egghead 的建议执行操作会使您面临 XSS 攻击

    将此代码拖放到 Razor 视图中,看看使用 Json.Encode 是安全的,并且 Newtonsoft 可以在 JavaScript 上下文中变得安全,但并非没有一些额外的工作。

    <script>
        var jsonEncodePotentialAttendees = @Html.Raw(Json.Encode(
            new[] { new { Name = "Samuel Jack</script><script>alert('jsonEncodePotentialAttendees failed XSS test')</script>" } }
        ));
        alert('jsonEncodePotentialAttendees passed XSS test: ' + jsonEncodePotentialAttendees[0].Name);
    </script>
    <script>
        var safeNewtonsoftPotentialAttendees = JSON.parse(@Html.Raw(HttpUtility.JavaScriptStringEncode(JsonConvert.SerializeObject(
            new[] { new { Name = "Samuel Jack</script><script>alert('safeNewtonsoftPotentialAttendees failed XSS test')</script>" } }), addDoubleQuotes: true)));
        alert('safeNewtonsoftPotentialAttendees passed XSS test: ' + safeNewtonsoftPotentialAttendees[0].Name);
    </script>
    <script>
        var unsafeNewtonsoftPotentialAttendees = @Html.Raw(JsonConvert.SerializeObject(
            new[] { new { Name = "Samuel Jack</script><script>alert('unsafeNewtonsoftPotentialAttendees failed XSS test')</script>" } }));
        alert('unsafeNewtonsoftPotentialAttendees passed XSS test: ' + unsafeNewtonsoftPotentialAttendees[0].Name);
    </script>
    

    另见:

    【讨论】:

    • 当他们添加 Json.Encode 时你知道吗?我不知道实际上有一种在页面上插入 json 的安全方法,而且我知道我过去对此进行了大量研究。
    • Json.Encode 从我记事起就已经存在,但缺点是它使用了 Microsoft 的输出非标准日期的实现(并且可能会做其他麻烦的事情)。我使用并鼓励使用 Newtonsoft 的 JsonConvert.SerializeObject 并结合适当的转义,因为它具有更好的输出。
    • 很高兴我向下滚动。我立即看到接受的答案,我希望有一种安全的方法来做到这一点。
    • HttpUtility.JavaScriptStringEncode 版本还对 JSON 中的引号进行了编码,如果直接在脚本中使用会导致无效[type='application/json'],这是一个遗憾。
    • 未来自己的注意事项:你要使用的是这个:@Html.Raw(Json.Encode())
    【解决方案2】:

    使用牛顿软件

    <script type="text/jscript">
      var potentialAttendees  = @(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.PotentialAttendees)))
    </script>
    

    【讨论】:

    • 这可能容易受到 Json.Encode 修复的 XSS 漏洞的影响,但您可以覆盖 JsonSerializerSettings.StringEscapeHandling 以启用编码。 stackoverflow.com/a/50336590/6950124
    【解决方案3】:

    你这样做:

    @Html.Raw(Json.Encode(Model.PotentialAttendees))
    

    在 Beta 2 之前的版本中,您可以这样做:

    @(new HtmlString(Json.Encode(Model.PotentialAttendees)))
    

    【讨论】:

    • 如果我想在我的对象属性中添加一些编码文本,我该怎么办? \,{\"UrlPart\":\"TjcolklFX5c\",\"Title\":\"When Mama Is\u0027t Home\"},{\" 例如。这会中断,因为 js 认为 ' 正在转义var a = ' ' 的原生字符串 decalration 同样适用于“”。有什么想法吗?
    • @SomeRandomName 你可以使用javascriptserializer@Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
    • 我们在 2017 年,使用 MVC 5,这个答案仍然是完美的!
    • 这个答案是唯一一个完美的答案。谢谢!
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2017-12-19
    • 1970-01-01
    相关资源
    最近更新 更多