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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19510532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:09:39  来源:igfitidea点击:

Registering a custom JsonConverter globally in Json.Net

c#json.net

提问by Mehran

Using Json.Net, I have properties in my objects which need special care in order to serialize / deserialize them. Making a descendant of JsonConverter, I managed to accomplish this successfully. This is the common way of doing this:

使用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());

My problem with this code is that I need to introduce my custom converter in every serialization / deserialization. In my project there are many cases that I cannot do that. For instance, I'm using other external projects which make use of Json.Net as well and they will be working on my SomeClassinstances. But since I don't want to or can't make change in their code, I have no way to introduce my converter.

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

Is there any way I can register my converter, using some staticmember perhaps, in Json.Net so no matter where serialization / deserialization happens, my converter is always present?

有什么办法可以static在 Json.Net 中注册我的转换器,也许使用某个成员,所以无论序列化/反序列化发生在哪里,我的转换器总是存在?

采纳答案by Brian Rogers

Yes, this is possible using Json.Net 5.0.5 or later. See JsonConvert.DefaultSettings.

是的,这可以使用 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

If you're using Web API, you can set up a converter globally like this instead:

如果您使用的是 Web API,则可以像这样全局设置转换器:

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

回答by Yishai Galatzer

Another approach (which wins in priority over the one @Brian mentions above) is to implement a custom contract resolver

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

JsonFormatter.SerializerSettings.ContractResolver = new CustomContractResolver();

And the implementation is rather straightforward

并且实现相当简单

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;
    }
}

Both methods are valid, this one is just a bigger hammer

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

回答by Florian Winter

This approach from the question ASP.NET Web API Custom JsonConverter is never calledworks with Web API:

这种来自ASP.NET Web API Custom JsonConverter is never called 问题的方法适用于 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());
}

Just put it somewhere into Global.asax.

只需将其放入Global.asax.

The other answers didn't work for me. DefaultSettingshas no effect on Web API actions, and the JsonFormatterconfiguration property does not seem to exist in the .NET framework version I use.

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