Is there a way to configure Json.Net to automatically encode all strings like HtmlEncode(myString)
when the model is serialized?
Asked
Active
Viewed 1.5k times
10

Brian Rogers
- 125,747
- 31
- 299
- 300

Buda Gavril
- 21,409
- 40
- 127
- 196
-
I wouldn't expect so - I'd expect it to encode strings *in JSON terms*. It would be very odd for it to *HTML-encode* the content. A JSON serializer's job is to get data from X to Y as JSON... for it to perform HTML encoding feels like massive scope creep. – Jon Skeet May 22 '17 at 14:52
-
Why not create a method where you pass in the object to be serialized and it returns an html encoded string result? – user1628733 May 22 '17 at 14:52
-
Is it what you have asked? [encoding](https://stackoverflow.com/questions/14106894/how-to-use-json-net-stringescapehandling-escapenonascii) – Artyom May 22 '17 at 14:54
-
@Artyom Yes, thank you, this was what I was looking for. Thank you – Buda Gavril May 22 '17 at 15:04
3 Answers
12
You could use a solution similar to the one in Selectively escape HTML in strings during deserialization, with a couple of minor changes:
- Change the
HtmlEncodingValueProvider
to apply the encoding inGetValue
rather thanSetValue
(so that it does the encoding on serialization rather than deserialization). - Change the resolver to apply the value provider to all string properties rather than looking for an attribute.
Here is what the resulting code would look like:
public class CustomResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
// Attach an HtmlEncodingValueProvider instance to all string properties
foreach (JsonProperty prop in props.Where(p => p.PropertyType == typeof(string)))
{
PropertyInfo pi = type.GetProperty(prop.UnderlyingName);
if (pi != null)
{
prop.ValueProvider = new HtmlEncodingValueProvider(pi);
}
}
return props;
}
protected class HtmlEncodingValueProvider : IValueProvider
{
PropertyInfo targetProperty;
public HtmlEncodingValueProvider(PropertyInfo targetProperty)
{
this.targetProperty = targetProperty;
}
// SetValue gets called by Json.Net during deserialization.
// The value parameter has the original value read from the JSON;
// target is the object on which to set the value.
public void SetValue(object target, object value)
{
targetProperty.SetValue(target, (string)value);
}
// GetValue is called by Json.Net during serialization.
// The target parameter has the object from which to read the string;
// the return value is the string that gets written to the JSON
public object GetValue(object target)
{
string value = (string)targetProperty.GetValue(target);
return System.Web.HttpUtility.HtmlEncode(value);
}
}
}
Use the custom ContractResolver
like this:
var settings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver(),
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(your_object, settings);
Fiddle: https://dotnetfiddle.net/RhFlk8

Brian Rogers
- 125,747
- 31
- 299
- 300
12
Try this:
var json = JObject.Parse("{'Name':'<script>alert(1);</script>'}");
var serializerSettings = new JsonSerializerSettings()
{
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
var result = JsonConvert.SerializeObject(json, serializerSettings);
result will be:
{"Name":"\u003cscript\u003ealert(1);\u003c/script\u003e"}

Mohammad Nikravan
- 1,543
- 2
- 19
- 22
-
This doesn't encode strings in the same way that `@Html.Encode()` does, but I found it helpful for my use case – Kevin Secrist May 14 '18 at 18:20
-
If your escaped HTML per above is loaded into eval contexts such as jQuery.html function, the script will be executed. Http Utility HTML encode is better. – gls123 Jun 11 '19 at 19:51
-
0
I found a very simple way doing this (WebAPI2).
When you set your object properties, just encode it with below.
myObject.encoded_field = HttpUtility.HtmlEncode(your_html_content)

BenW
- 1,393
- 1
- 16
- 26