Wie schreibe ich mit Razor nicht codierten Json in meine Ansicht?

153

Ich versuche, ein Objekt als JSON mit Razor in meine Asp.Net MVC-Ansicht zu schreiben:

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

Das Problem ist, dass in der Ausgabe der JSON codiert ist und mein Browser ihn nicht mag. Beispielsweise:

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

Wie bringe ich Razor dazu, nicht codierten JSON auszugeben?

Samuel Jack
quelle

Antworten:

190

Sie machen:

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

In früheren Versionen als Beta 2 hat es Ihnen gefallen:

@(new HtmlString(Json.Encode(Model.PotentialAttendees)))
Lorenzo
quelle
3
Was kann ich tun, wenn ich codierten Text in meinen Objekteigenschaften haben möchte? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "When Mama Isn \ u0027t Home \"}, {\ "Zum Beispiel native String-Dekalration von var a = '' Gleiches gilt für "". Jede Idee?
SomeRandomName
@SomeRandomName können Sie javascriptserializerfür das wie verwenden @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool
Wir verwenden MVC 5 im Jahr 2017 und diese Antwort ist immer noch perfekt!
Gabriel Espinoza
Diese Antwort ist die einzige, die perfekt funktioniert. Vielen Dank!
Jean-Paul
43

Newtonsofts JsonConvert.SerializeObjectverhält sich nicht so wie Json.Encodeund wenn Sie das tun, was @ david-k-egghead vorschlägt, sind Sie für XSS-Angriffe geöffnet .

Legen Sie diesen Code in einer Razor-Ansicht ab, um zu sehen, dass die Verwendung Json.Encodesicher ist und dass Newtonsoft im JavaScript-Kontext sicher gemacht werden kann, jedoch nicht ohne zusätzliche Arbeit.

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

Siehe auch:

Jeremy Cook
quelle
Haben Sie eine Idee, wann sie Json.Encode hinzugefügt haben? Ich wusste nicht, dass es tatsächlich eine sichere Möglichkeit gibt, json auf der Seite einzufügen, und ich weiß, dass ich in der Vergangenheit viel darüber recherchiert habe.
Chris Marisic
1
Json.EncodeEs gibt es schon so lange, wie ich mich erinnern kann, aber der Nachteil ist, dass es die Implementierung von Microsoft verwendet, die nicht standardmäßige Daten ausgibt (und möglicherweise andere störende Dinge tut). Ich benutze und ermutige die Verwendung von Newtonsoft in JsonConvert.SerializeObjectKombination mit der richtigen Flucht, weil es eine bessere Ausgabe hat.
Jeremy Cook
2
Ich bin froh, dass ich nach unten gescrollt habe. Sofort sah ich die akzeptierte Antwort und hoffte, dass es einen sicheren Weg gab, dies zu tun.
frostymarvelous
Die Version HttpUtility.JavaScriptStringEncode codiert auch die Anführungszeichen im JSON und macht sie ungültig, wenn sie direkt in einem Skript [type = 'application / json'] verwendet wird, was schade ist.
Pete Kirkham
1
Hinweis für das zukünftige Selbst: Das, was Sie verwenden möchten, ist Folgendes: @ Html.Raw (Json.Encode ())
Pangamma
12

Verwenden von Newtonsoft

<script type="text/jscript">
  var potentialAttendees  = @(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.PotentialAttendees)))
</script>
Ravi Ram
quelle
1
Dies ist möglicherweise anfällig für XSS-Schwachstellen, die von Json.Encode behoben werden. Sie können diese jedoch überschreiben JsonSerializerSettings.StringEscapeHandling, um die Codierung zu aktivieren. stackoverflow.com/a/50336590/6950124
Kevin Secrist