How do I write unencoded Json to my View using Razor?

asp.net MvcJsonRazor

asp.net Mvc Problem Overview


I'm trying to write an object as JSON to my Asp.Net MVC View using Razor, like so:

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

The problem is that in the output the JSON is encoded, and my browser doesn't like it. For example:

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

How do I get Razor to emit unencoded JSON?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

You do:

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

In releases earlier than Beta 2 you did it like:

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

Solution 2 - asp.net Mvc

Newtonsoft's JsonConvert.SerializeObject does not behave the same as Json.Encode and doing what @david-k-egghead suggests opens you up to XSS attacks.

Drop this code into a Razor view to see that using Json.Encode is safe, and that Newtonsoft can be made safe in the JavaScript context but is not without some extra work.

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

See also:

Solution 3 - asp.net Mvc

Using Newtonsoft

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSamuel JackView Question on Stackoverflow
Solution 1 - asp.net MvcLorenzoView Answer on Stackoverflow
Solution 2 - asp.net MvcJeremy CookView Answer on Stackoverflow
Solution 3 - asp.net MvcRavi RamView Answer on Stackoverflow