In ASP.Net 5 there is a JsonHelper
directly available in the razor views via @Json.Serialize
, so you can write something like this in your razor view:
var foo = @Json.Serialize(model);
This is very similar to manually doing:
var foo = @Html.Raw(JsonConvert.SerializeObject(model))
The problem in both cases is that JSON.Net by default serializes but does not XSS-sanitizes the output. This means the contents of model are not escaped, leaving your code open for XSS attacks if model depends on user input. For example:
@{
var model = new
{
prop1 = 1,
prop2 = "</script><script>alert('o hai');</script>",
prop3 = false
};
}
var foo = @Json.Serialize(model);
You could use the Json.Serialize
overload that lets you specify JsonSerializerSettings
, so you can set StringEscapeHandling
as EscapeHtml:
HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped.
var foo = @Json.Serialize(model, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeHtml });
PS. I have raised an issue on github to include default html escaping in the JsonHelper.
Approaches used in previous versions
If you search about this same question on stack overflow, you will see there used to be a Json.Encode
helper in earlier versions of MVC, so you could serialize like this, manually performing the json serialization. This seems replaced by Json.Serialize
which is not safe by default.
There also used to be a helper HttpUtility.JavaScriptStringEncode
that could be used to manually encode json literals. This seems to be there in ASP.Net 5 as IJavaScriptStringEncoder
. The only problem is that when combined with Newtonsoft.Json (The default json formatter in ASP.Net 5), it will encode too much for a valid json literal (like the double quotes in property names). However it will produce a valid string that can be parsed on the browser with JSON.parse (So probably this approach should work too):
@inject Microsoft.Extensions.WebEncoders.IJavaScriptStringEncoder encoder;
...
var foo = JSON.parse("@encoder.JavaScriptStringEncode(JsonConvert.SerializeObject(model))");
Be also aware that by looking at the newest source code, the IJavaScriptStringEncoder
will be replaced by System.Text.Encodings.Web.JavaScriptEncoder
in RC2.