¿Cómo escribo Json sin codificar en mi vista usando Razor?


153

Estoy tratando de escribir un objeto como JSON en mi Asp.Net MVC View usando Razor, así:

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

El problema es que en la salida el JSON está codificado y a mi navegador no le gusta. Por ejemplo:

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

¿Cómo consigo que Razor emita JSON sin codificar?

Respuestas:


190

Tú lo haces:

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

En versiones anteriores a Beta 2 lo hiciste como:

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

3
¿Qué puedo hacer si quiero texto codificado en las propiedades de mis objetos? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "When Mama Isn \ u0027t Home \"}, {\ "Por ejemplo. Esto se romperá porque js piensa que el 'está escapando del decalration secuencia nativa de var a = '' mismo va para "" idea de Anny.?
— SomeRandomName

@SomeRandomName que puedes usar javascriptserializerpara eso @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
— vikscool

Estamos en 2017, usando MVC 5 y esta respuesta sigue siendo perfecta.
— Gabriel Espinoza

Esta respuesta es la única que funciona perfectamente. ¡Gracias!
— Jean-Paul

43

Newtonsoft JsonConvert.SerializeObjectno se comporta igual Json.Encodey hacer lo que sugiere @ david-k-egghead te abre a ataques XSS .

Coloque este código en una vista de Razor para ver que el uso Json.Encodees seguro y que Newtonsoft se puede hacer seguro en el contexto de JavaScript, pero no sin algún trabajo adicional.

<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>

Ver también:


¿Tienes alguna idea cuando agregaron Json.Encode? No sabía que en realidad había una forma segura de insertar json en la página y sé que hice muchas investigaciones al respecto en el pasado.
— Chris Marisic

1
Json.Encodeha existido desde que tengo memoria, pero la desventaja es que usa la implementación de Microsoft que genera fechas no estándar (y puede hacer otras cosas molestas). Uso y aliento el uso de Newtonsoft JsonConvert.SerializeObjectcombinado con un escape adecuado porque tiene una mejor salida.
— Jeremy Cook

2
Me alegro de haberme desplazado hacia abajo. Inmediatamente vi la respuesta aceptada, esperaba que hubiera una forma segura de hacer esto.
— frostymarvelous

La versión HttpUtility.JavaScriptStringEncode también codifica las comillas en el JSON, haciéndolo inválido si se usa directamente en un script [type = 'application / json'], lo cual es una pena.
— Pete Kirkham

1
Nota para el yo futuro: El que desea usar es este: @ Html.Raw (Json.Encode ())
— Pangamma

12

Usando Newtonsoft

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

1
Esto es potencialmente vulnerable a las vulnerabilidades XSS que corrige Json.Encode, pero puede anularlo JsonSerializerSettings.StringEscapeHandlingpara habilitar la codificación. stackoverflow.com/a/50336590/6950124
— Kevin Secrist
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.