Как я могу написать некодированный Json в мой вид с помощью Razor?


153

Я пытаюсь записать объект как JSON в свой Asp.Net MVC View, используя 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>

Как мне заставить Razor выдавать незашифрованный JSON?

Ответы:


190

Вы делаете:

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

В выпусках, предшествующих Beta 2, вы делали это так:

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

3
Что я могу сделать, если мне нужен кодированный текст в свойствах моих объектов? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "Когда мама не дома \"}, {\ "Например. Это сломается, потому что js думает, что 'ускользает от родная строка декалирования var a = '' то же самое относится к "". любая идея?
SomeRandomName

@SomeRandomName, который вы можете использовать javascriptserializerдля этого, как @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool

Мы в 2017 году используем MVC 5, и этот ответ все еще идеален!
Габриэль Эспиноза

Этот ответ - единственный, который отлично работает. Спасибо!
Жан-Поль

43

Ньютонсофт JsonConvert.SerializeObjectведет себя не так, как Json.Encodeи делает то, что предлагает @ david-k-egghead, открывает вам возможность атак XSS .

Перенесите этот код в представление Razor, чтобы увидеть, что использование 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
Рад, что прокрутил вниз. Сразу же я увидел принятый ответ, я надеялся, что есть безопасный способ сделать это.
морозный

Версия HttpUtility.JavaScriptStringEncode также кодирует кавычки в JSON, делая его недействительным, если используется непосредственно в скрипте [type = 'application / json'], что очень жаль.
Пит Киркхем

1
Примечание для будущего себя: то, что вы хотите использовать, это: @ Html.Raw (Json.Encode ())
Pangamma

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
Кевин Секрист
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.