Newtonsoft JSON DefaultSettings per Assembly

Refresh

April 2019

Views

44 time

1

In order to automatically trim all input strings and remove new lines, I developed an implementation of JsonConverter<string> and registered it in Startup with

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    Converters = new List<JsonConverter>
    {
        new StringTrimmer()
    }
};

This works, but the string trimmer is negatively impacting third-party assemblies. Is there a way I can scope the default settings to my application's assembly, or register an instance with JsonConvert.Create(mySettings)? Or is there another method which I could automatically trim all input without JsonConvert?

3 answers

2

If you only care about changing how ASP.NET Core serializes JSON, then you can configure the JsonSerializerSettings for the MVC framework explicitly using AddJsonOptions:

services.AddMvc()
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.Converters.Add(new StringTrimmer());
    });
2

You can programmatically apply your converter only within certain assemblies by using a custom ContractResolver like this:

public class CustomResolver : DefaultContractResolver
{
    private Assembly[] TargetAssemblies { get; set; }

    public CustomResolver(params Assembly[] targetAssemblies)
    {
        TargetAssemblies = targetAssemblies;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization ms)
    {
        JsonProperty prop = base.CreateProperty(member, ms);

        if (prop.PropertyType == typeof(string) &&
            TargetAssemblies.Contains(prop.DeclaringType.Assembly))
        {
            prop.Converter = new StringTrimmer();
        }

        return prop;
    }
}

Then use it within your default settings like this, where Foo is replaced with one of the known classes in your application's assembly:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ContractResolver = new CustomResolver(typeof(Foo).Assembly)
};

You can add more than one assembly if you need to, e.g.:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ContractResolver = new CustomResolver(typeof(Foo).Assembly, typeof(Bar).Assembly)
};
0

Make your StringTrimmer aware of the types (and their assemblies) it's dealing with. WriteJson() and ReadJson() have access to the type of object. Apply the trimming only to the types you care about.