gpt4 book ai didi

c# - 如何覆盖默认 JsonConverter(在属性中指定)

转载 作者:行者123 更新时间:2023-12-03 19:39:10 25 4
gpt4 key购买 nike

我希望以下 Author 类型具有默认的 JsonConverter,并且能够在运行时覆盖它。

[JsonConverter(typeof(BaseJsonConverter))]
public class Author
{
// The ID of an author entity in the application.
public int ID { set; get; }

// The ID of an Author entity in its source.
public string SourceID { set; set; }
}

我使用以下代码覆盖默认转换器(即 BaseJsonConverter)。

public class AlternativeConverter : BaseJsonConverter
{ // the serializer implementation is removed for clarity. }

// Deserialize using AlternativeConverter:
var author = JsonConvert.DeserializeObject<Author>(jsonString, new AlternativeConverter());

问题

使用上面的调用,首先构建了AlternativeConverter;然而,然后 BaseJsonConverter 的一个实例被初始化并用于反序列化。因此,从未使用过 AlternativeConverter

Executable example: https://dotnetfiddle.net/l0bgYO


用例

应用是将从不同来源获取的不同JSON对象转换为通用的C#类型。通常数据来 self 们定义默认转换器的源(即 BaseJsonConverter),对于来自其他源的数据,我们为每个源定义不同的转换器。


背景

我知道诸如 this one 之类的方法,而且我确实部分地使用了类似的方法。引用那篇文章,我需要根据输入源使用不同的 _propertyMappings,因为在我的应用程序中,属性到属性的映射不是一对一的。例如,我有以下 JSON 对象:

{
"id":123
}

// and

{
"id":"456"
}

第一个 JSON 对象应该被反序列化到:

author.ID = 123
author.SourceID = null

第二个 JSON 对象应该被反序列化为:

author.ID = 0
author.SourceID = "456"

最佳答案

您可以使用自定义 ContractResolver以编程方式覆盖 [JsonConverter] 属性。要解决您的问题,您可以制作这样的自定义解析器:

public class CustomResolver : DefaultContractResolver
{
private Dictionary<Type, JsonConverter> Converters { get; set; }

public CustomResolver(Dictionary<Type, JsonConverter> converters)
{
Converters = converters;
}

protected override JsonObjectContract CreateObjectContract(Type objectType)
{
JsonObjectContract contract = base.CreateObjectContract(objectType);
if (Converters.TryGetValue(objectType, out JsonConverter converter))
{
contract.Converter = converter;
}
return contract;
}
}

然后,当您想使用 AlternativeConverter 代替 BaseJsonConverter 时,您可以像这样使用自定义解析器:

// map the `Author` type to the `AlternativeConverter`
var converters = new Dictionary<Type, JsonConverter>()
{
{ typeof(Author), new AlternativeConverter() }
};

// Create a resolver with the converter mapping and add it to the serializer settings
var settings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver(converters)
};

// Use the settings when deserializing
var author = JsonConvert.DeserializeObject<Author>(jsonString, settings);

演示 fiddle :https://dotnetfiddle.net/cu0igV


当然,如果您真正对这些转换器所做的只是将属性重新映射到不同的名称,您可以首先使用 ContractResolver 并完全摆脱转换器。参见 Json.NET deserialize or serialize json string and map properties to different property names defined at runtime 有关该方法的更多信息。

关于c# - 如何覆盖默认 JsonConverter(在属性中指定),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60626892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com