[英]How to Override a Default JsonConverter (specified in an attribute)
I would like the following Author
type to have a default JsonConverter
, and be able to override it at runtime.我希望以下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; }
}
I used the following code to override the default converter (ie, BaseJsonConverter
).我使用以下代码覆盖默认转换器(即BaseJsonConverter
)。
public class AlternativeConverter : BaseJsonConverter
{ // the serializer implementation is removed for clarity. }
// Deserialize using AlternativeConverter:
var author = JsonConvert.DeserializeObject<Author>(jsonString, new AlternativeConverter());
Using the above call, the AlternativeConverter
is first constructed;使用上面的调用,首先构造了AlternativeConverter
; however, then an instance of BaseJsonConverter
is initialized and used for deserialization.然而,然后BaseJsonConverter
一个实例被初始化并用于反序列化。 So, the AlternativeConverter
is never used.因此,从不使用AlternativeConverter
。
Executable example: https://dotnetfiddle.net/l0bgYO可执行示例:https://dotnetfiddle.net/l0bgYO
The application is to convert different JSON objects, obtained from different sources, to a common C# type.应用程序是将从不同来源获得的不同 JSON 对象转换为通用 C# 类型。 Commonly data comes from a source for that we define the default converter (ie, BaseJsonConverter
), and for data coming from other sources, we define different converters per each.通常数据来自我们定义默认转换器的源(即BaseJsonConverter
),对于来自其他源的数据,我们为每个源定义不同的转换器。
I am aware of methods such as this one , and indeed I am using similar method partially.我知道的方法,如这一个,而事实上我使用类似的方法部分。 With ref to that article, I need to have different _propertyMappings
depending on the source of input, because in my application attribute to property mapping is not one-to-one.参考那篇文章,我需要根据输入源使用不同的_propertyMappings
,因为在我的应用程序中,属性到属性的映射不是一对一的。 For instance, I have the following JSON objects:例如,我有以下 JSON 对象:
{
"id":123
}
// and
{
"id":"456"
}
where the first JSON object should be deserialized to:第一个 JSON 对象应该反序列化为:
author.ID = 123
author.SourceID = null
and the second JSON object should be deserialized as:并且第二个 JSON 对象应该反序列化为:
author.ID = 0
author.SourceID = "456"
You can use a custom ContractResolver
to override a [JsonConverter]
attribute programmatically.您可以使用自定义ContractResolver
以编程方式覆盖[JsonConverter]
属性。 To solve your problem you could make a custom resolver like this:要解决您的问题,您可以制作这样的自定义解析器:
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;
}
}
Then, when you wanted to use the AlternativeConverter
in place of the BaseJsonConverter
, you could use the custom resolver like this:然后,当您想使用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);
Demo Fiddle: https://dotnetfiddle.net/cu0igV演示小提琴: https : //dotnetfiddle.net/cu0igV
Of course, if all you're really doing with these converters is remapping properties to different names, you could just use a ContractResolver
for that in the first place and get rid of the converters altogether.当然,如果您真正使用这些转换器所做的只是将属性重新映射到不同的名称,那么您可以首先使用ContractResolver
并完全摆脱转换器。 See Json.NET deserialize or serialize json string and map properties to different property names defined at runtime for more information on that approach.有关该方法的更多信息,请参阅Json.NET 反序列化或序列化 json 字符串并将属性映射到在运行时定义的不同属性名称。
I think you should try to use different JsonSerializerSettings
instances for different data sources, with different Converters collections.我认为您应该尝试为不同的数据源使用不同的JsonSerializerSettings
实例,以及不同的Converters集合。 And remove JsonConverter
attributes from your classes.并从您的类中删除JsonConverter
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.