Як написати незашифрований Json до мого перегляду за допомогою Razor?


153

Я намагаюся записати об’єкт як JSON на мій перегляд MVC Asp.Net за допомогою Razor, наприклад:

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

Як змусити Бритву випромінювати незашифрований JSON?

Відповіді:


190

Ти робиш:

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

У випусках раніше, ніж Beta 2, ви зробили це так:

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

3
Що я можу зробити, якщо мені потрібно якийсь закодований текст у властивостях моїх об’єктів? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "Коли мама Isn \ u0027t Home \"}, {\ "Наприклад, це зламається, оскільки js вважає, що" втече декаляція рідного рядка var a = '' те ж саме стосується "". anny idea?
SomeRandomName

@SomeRandomName ви можете використовувати javascriptserializerдля подібного @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool

Ми в 2017 році, використовуючи MVC 5, і ця відповідь все ще ідеальна!
Габріель Еспіноза

Ця відповідь єдина, яка прекрасно працює. Дякую!
Жан-Пол

43

Ньютонсофт JsonConvert.SerializeObjectведе себе не так, як Json.Encodeі те, що пропонує @ david-k-egghead відкриває вас до XSS-атак .

Закиньте цей код у вигляд «Бритви», щоб побачити, що використання 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 на сторінку, і я знаю, що я багато досліджував це в минулому.
Кріс Марісіч

1
Json.Encodeя існував так довго, як я пам'ятаю, але недоліком є ​​те, що він використовує реалізацію Microsoft, яка виводить нестандартні дати (і може робити інші клопітні речі). Я використовую і заохочую використання Newtonsoft у JsonConvert.SerializeObjectпоєднанні з правильним втечею, оскільки він має кращий вихід.
Джеремі Кук

2
Радий, що я прокрутився вниз. Відразу побачивши прийняту відповідь, я сподівався, що це безпечний спосіб зробити це.
frostymarvelous

Версія HttpUtility.JavaScriptStringEncode також кодує лапки в JSON, що робить її недійсною, якщо вона використовується безпосередньо в сценарії [type = 'application / json'], що шкода.
Піт Кіркхем

1
Примітка до майбутнього самоврядування: Ви хочете використовувати це: @ Html.Raw (Json.Encode ())
Пангама

12

Використання Newtonsoft

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

1
Це потенційно вразливе до вразливості XSS, яку виправляє Json.Encode, але ви можете змінити значення, JsonSerializerSettings.StringEscapeHandlingщоб увімкнути кодування. stackoverflow.com/a/50336590/6950124
Кевін Secrist
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.