Come faccio a scrivere Json non codificato su View usando Razor?


153

Sto cercando di scrivere un oggetto come JSON sul mio Asp.Net MVC View usando Razor, in questo modo:

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

Il problema è che nell'output JSON è codificato e al mio browser non piace. Per esempio:

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

Come faccio a far sì che Razor emetta JSON non codificato?

Risposte:


190

Tu fai:

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

Nelle versioni precedenti alla Beta 2 ti è piaciuto:

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

3
Cosa posso fare se desidero del testo codificato nelle proprietà dei miei oggetti? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "Quando la mamma non è in casa \"}, {\ "Ad esempio. Ciò interromperà perché js pensa che 'sta scappando dal' decalation stringa nativa di var a = '' stesso vale per "". idea anny?
— SomeRandomName

@SomeRandomName è possibile utilizzare javascriptserializerper questo tipo @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
— vikscool

Siamo nel 2017, usando MVC 5 e questa risposta è ancora perfetta!
— Gabriel Espinoza,

Questa risposta è l'unica che funziona perfettamente. Grazie!
— Jean-Paul,

43

Newtonsoft JsonConvert.SerializeObjectnon si comporta allo stesso modo Json.Encodee fare ciò che suggerisce @ david-k-egghead ti apre agli attacchi XSS .

Trascina questo codice in una vista Razor per vedere che l'uso Json.Encodeè sicuro e che Newtonsoft può essere reso sicuro nel contesto JavaScript ma non è privo di lavoro extra.

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

Guarda anche:


Hai idea di quando hanno aggiunto Json.Encode? Non sapevo che in realtà esistesse un modo sicuro per inserire json nella pagina e so di aver fatto molte ricerche in passato.
— Chris Marisic,

1
Json.Encodeè in circolazione da quanto posso ricordare, ma il rovescio della medaglia è che utilizza l'implementazione di Microsoft che genera date non standard (e può fare altre cose fastidiose). Uso e incoraggio l'uso di Newtonsoft JsonConvert.SerializeObjectcombinato con la corretta evasione perché ha un output migliore.
— Jeremy Cook,

2
Sono contento di averlo fatto scorrere verso il basso. Immediatamente ho visto la risposta accettata, ho sperato che ci fosse un modo sicuro per farlo.
— frostymarvelous,

La versione HttpUtility.JavaScriptStringEncode codifica anche le virgolette in JSON, rendendolo non valido se utilizzato direttamente in uno script [type = 'application / json'], che è un peccato.
— Pete Kirkham,

1
Nota per il futuro: quello che vuoi usare è questo: @ Html.Raw (Json.Encode ())
— Pangamma

12

Utilizzando Newtonsoft

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

1
Ciò è potenzialmente vulnerabile alle vulnerabilità XSS che Json.Encode risolve, ma è possibile ignorare JsonSerializerSettings.StringEscapeHandlingper abilitare la codifica. stackoverflow.com/a/50336590/6950124
— Kevin Secrist
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.