CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class Program
{
public static void Main()
{
Foo foo = new Foo
{
Name = "<b>Foo Bar</b>",
Description = @"<p class=""intro"">Bada Boom Bada Bing</p>"
};
var settings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver(),
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(foo, settings);
Console.WriteLine(json);
}
}
class Foo
{
public string Name { get; set; }
public string Description { get; set; }
}
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 HttpUtility.HtmlEncode(value);
}
}
}
// Note: Following is a stand-in for the System.Web.HttpUtility class,
// as dotnetfiddle apparently does not provide access to the System.Web namespace.
// In your production code, please use the real version provided by .NET; do NOT use this stand-in class.
public static class HttpUtility
{
public static string HtmlEncode(string s)
{
if (s != null)
{
// \u0026 is an ampersand; needed here to get around a dotnetfiddle bug
s = s.Replace("\u0026", "\u0026amp;")
.Replace("<", "\u0026lt;")
.Replace(">", "\u0026gt;")
.Replace("\"", "\u0026quot;");
}
return s;
}
}