Razor를 사용하여 인코딩되지 않은 Json을 View에 작성하는 방법


153

Razor를 사용하여 Asp.Net MVC View에 JSON으로 객체를 쓰려고합니다.

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

베타 2 이전 릴리스에서는 다음과 같이했습니다.

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

3
객체 속성에 인코딩 된 텍스트를 원하는 경우 어떻게해야합니까? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "예를 들어, Mama Isn \ u0027t Home \"}, {\ "예를 들어, 이로 인해 j는 ' var a = ''의 기본 문자열 디칼 레이션은 ""에도 적용됩니다. anny idea?
SomeRandomName

당신이 사용할 수있는 @SomeRandomName javascriptserializer그런를 위해 @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool

우리는 2017 년 MVC 5를 사용하고 있으며이 답변은 여전히 ​​완벽합니다!
Gabriel Espinoza

이 답변은 완벽하게 작동하는 유일한 것입니다. 감사!
Jean-Paul

43

Newtonsoft 's JsonConvert.SerializeObjectJson.Encode@ david-k-egghead가 제안한 것과 동일하게 동작하지 않으며 XSS 공격 까지 개방합니다 .

이 코드를 Razor 뷰에 드롭하여 사용 Json.Encode이 안전하고 JavaScript 컨텍스트에서 Newtonsoft를 안전하게 만들 수 있지만 추가 작업이없는 것은 아닙니다.

<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을 삽입하는 안전한 방법이 있다는 것을 알지 못했고 과거에 많은 연구를했음을 알고 있습니다.
Chris Marisic

1
Json.Encode내가 기억할 수있는 한 주변에 있었지만 단점은 비표준 날짜를 출력하는 Microsoft의 구현을 사용한다는 것입니다 (다른 귀찮은 일을 할 수도 있음). 나는 JsonConvert.SerializeObject출력이 더 좋기 때문에 Newtonsoft 와 적절한 이스케이프를 함께 사용하고 권장합니다 .
Jeremy Cook

2
다행스럽게 스크롤을 내렸다. 나는 즉시 받아 들인 대답을 보았고 안전한 방법이 있기를 바랐다.
frostymarvelous

HttpUtility.JavaScriptStringEncode 버전은 JSON에서 따옴표를 인코딩하여 스크립트 [type = 'application / json']에서 직접 사용하는 경우에는 유효하지 않은 렌더링으로 표시합니다.
Pete Kirkham

1
미래의 자기 자신에 대한 참고 사항 : 사용하려는 것은 다음과 같습니다. @ Html.Raw (Json.Encode ())
Pangamma

12

Newtonsoft 사용

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

1
이는 Json.Encode가 수정 한 XSS 취약점에 잠재적으로 취약하지만 JsonSerializerSettings.StringEscapeHandling인코딩을 활성화 하기 위해를 재정의 할 수 있습니다 . stackoverflow.com/a/50336590/6950124
Kevin Secrist
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.