Подтвердить что ты не робот

Регистрация пользовательского JsonConverter по всему миру в Json.Net

Используя 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. Но поскольку я не хочу или не могу внести изменения в свой код, у меня нет способа представить свой конвертер.

Можно ли каким-либо образом зарегистрировать конвертер, используя, возможно, некоторый член static в Json.Net, независимо от того, где происходит сериализация/десериализация, мой конвертер всегда присутствует?

4b9b3361

Ответ 1

Да, это возможно с помощью 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());

Ответ 2

Другой подход (который выигрывает в приоритете над одним из приведенных выше @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;
    }
}

Оба метода действительны, это просто больший молот

Ответ 3

Этот подход из вопроса ASP.NET Web API Custom JsonConverter никогда не называется, работает с 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 конфигурации JsonFormatter, по-видимому, не существует в используемой мной версии .NET Framework.