Samuel Jack
Samuel Jack

Reputation: 33270

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

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?

Upvotes: 164

Views: 89724

Answers (3)

Jeremy Cook
Jeremy Cook

Reputation: 22073

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:

Upvotes: 47

Ravi Ram
Ravi Ram

Reputation: 24488

Using Newtonsoft

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

Upvotes: 15

Lorenzo
Lorenzo

Reputation: 29427

You do:

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

In releases earlier than Beta 2 you did it like:

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

Upvotes: 204

Related Questions