在 Json.Net 中全局注册自定义 JsonConverter

本文关键字:注册 自定义 JsonConverter 全局 Json Net | 更新日期: 2023-09-27 18:36:18

使用 Json.Net,我的对象中有需要特别注意的属性,以便序列化/反序列化它们。作为JsonConverter的后代,我成功地完成了这项工作。这是执行此操作的常见方法:

public class SomeConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        ...
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        ...
    }
    public override bool CanConvert(Type objectType)
    {
        ...
    }
}
class SomeClass
{
    [JsonProperty, JsonConverter(typeof(SomeConverter))]
    public SomeType SomeProperty;
}
//Later on, in code somewhere
SomeClass SomeObject = new SomeClass();
string json = JsonConvert.SerializeObject(SomeObject, new SomeConverter());

我对这段代码的问题是我需要在每个序列化/反序列化中引入我的自定义转换器。在我的项目中,有很多情况我无法做到这一点。例如,我正在使用其他也使用 Json.Net 的外部项目,他们将在我的SomeClass实例上工作。 但是由于我不想或不能更改他们的代码,所以我无法介绍我的转换器。

有什么方法可以在 Json.Net 中使用一些static成员注册我的转换器,这样无论在哪里发生序列化/反序列化,我的转换器始终存在?

在 Json.Net 中全局注册自定义 JsonConverter

是的,使用 Json.Net 5.0.5 或更高版本可以这样做。 请参阅JsonConvert.DefaultSettings

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new SomeConverter() }
};
// Later on...
string json = JsonConvert.SerializeObject(someObject);  // this will use SomeConverter

如果使用的是 Web API,则可以改为全局设置转换器,如下所示:

var config = GlobalConfiguration.Configuration;
var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.Converters.Add(new SomeConverter());

另一种方法(优先于上面提到的方法@Brian)是实现自定义协定解析器

JsonFormatter.SerializerSettings.ContractResolver = new CustomContractResolver();

而且实现相当简单

public class CustomContractResolver : DefaultContractResolver
{
    private static readonly JsonConverter _converter = new MyCustomConverter();
    private static Type _type = typeof (MyCustomType);
    protected override JsonConverter ResolveContractConverter(Type objectType)
    {
        if (objectType == null || !_type.IsAssignableFrom(objectType)) // alternatively _type == objectType
        {
            return base.ResolveContractConverter(objectType);
        }
        return _converter;
    }
}

两种方法都有效,这只是一个更大的锤子

这种方法来自 Web API

自定义 JsonConverter 的问题 ASP.NET 永远不会与 Web API 一起使用:

// Add a custom converter for Entities.
foreach (var formatter in GlobalConfiguration.Configuration.Formatters)
{
  var jsonFormatter = formatter as JsonMediaTypeFormatter;
  if (jsonFormatter == null)
    continue;
  jsonFormatter.SerializerSettings.Converters.Add(new MyConverter());
}

只需将其放入Global.asax的某个地方即可.

其他答案对我不起作用。 DefaultSettings对 Web API 操作没有影响,并且JsonFormatter配置属性在我使用的 .NET 框架版本中似乎不存在。