Razor kullanarak görünümümde kodlanmamış Json'u nasıl yazarım?


153

Jilet kullanarak Asp.Net MVC görünümüne JSON olarak bir nesne yazmaya çalışıyorum, şöyle:

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

Sorun çıktıda JSON kodlanmış olması ve tarayıcım bunu sevmiyor. Örneğin:

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

Razor'un kodlanmamış JSON yaymasını nasıl sağlarım?

Yanıtlar:


190

Siz yapıyorsunuz:

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

Beta 2'den önceki sürümlerde şunları beğendiniz:

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

3
Nesnelerimin özelliklerinde bazı kodlanmış metinler istersem ne yapabilirim? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "Mama Isn \ u0027t Home \"}, {\ "Örneğin, bu durum js ' var a = '' aynı yerel dize çıkartma aynı "" için geçerli. herhangi bir fikir?
SomeRandomName

Şunun javascriptserializeriçin kullanabilirsiniz@Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool

MVC 5'i kullanarak 2017'deyiz ve bu cevap hala mükemmel!
Gabriel Espinoza

Bu cevap mükemmel çalışan tek cevaptır. Teşekkürler!
Jean-Paul

43

Newtonsoft's JsonConvert.SerializeObjectaynı şekilde davranmaz Json.Encodeve @ david-k-egghead'in önerdiğini yapmak sizi XSS saldırılarına kadar açar .

Kullanmanın Json.Encodegüvenli olduğunu ve Newtonsoft'un JavaScript bağlamında güvenli hale getirilebileceğini, ancak fazladan bir çalışma yapılmadığını görmek için bu kodu bir Razor görünümüne bırakın .

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

Ayrıca bakınız:


Json.Encode'u eklediklerinde herhangi bir fikriniz var mı? Sayfada json eklemenin güvenli bir yolu olduğunu bilmiyordum ve geçmişte çok fazla araştırma yaptığımı biliyorum.
Chris Marisic

1
Json.Encodehatırlayabildiğim kadarıyla oldu, ama olumsuz, standart olmayan tarihler (ve diğer rahatsız edici şeyler yapabilir) Microsoft'un uygulamasını kullanmasıdır. Daha JsonConvert.SerializeObjectiyi bir çıktıya sahip olduğu için Newtonsoft'un uygun kaçışla birlikte kullanılmasını ve kullanılmasını teşvik ediyorum .
Jeremy Cook

2
Sevindim aşağı kaydırdım. Kabul edilen cevabı hemen gördüm, bunu yapmanın güvenli bir yolu olduğunu umdum.
16:13

HttpUtility.JavaScriptStringEncode sürümü JSON'daki tırnak işaretlerini de kodlar, bu da üzücü olan bir komut dosyasında [type = 'application / json'] doğrudan kullanıldığında geçersiz kılar.
Pete Kirkham

1
Gelecekteki benlik için not: Kullanmak istediğiniz kişi şudur: @ Html.Raw (Json.Encode ())
Pangamma

12

Newtonsoft'u kullanma

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

1
Bu, Json.Encode'un düzelttiği XSS güvenlik açıklarına karşı potansiyel olarak zayıftır, ancak JsonSerializerSettings.StringEscapeHandlingkodlamayı etkinleştirmek için. stackoverflow.com/a/50336590/6950124
Kevin Secrist
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.