问题描述
我编写了一个名为 CompententsConverter
的自定义 JsonConverter 并且它工作正常,但是我很好奇是否有一种方法可以使用带有 params object[] converterParameters 的备用构造函数并传递我自己的自定义参数来自相应的属性。
同样,我不确定如何实际检索 JsonConverter 类定义中的参数,或者是否可以使用 JsonConverter 属性来执行此操作。
在模型内部,具有理论参数的属性,其中 some_parameter_here
是 constant expression 的占位符:
[JsonProperty("components")]
[JsonConverter(typeof(ComponentsConverter),some_parameter_here)]
public List<ComponentModel> Components { get; set; }
ComponentsConverter 自定义 JsonConverter:
public class ComponentsConverter : JsonConverter
{
public override bool CanConvert (Type t) => t == typeof(List<ComponentModel>);
public override object ReadJson (JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
{
// ... any way to access params object[] customParameters here?
}
public override void WriteJson (JsonWriter writer,object value,JsonSerializer serializer)
{
// ...
}
}
能够通过使用这些额外参数为特定模型属性定义一些自定义转换行为会很好。
解决方法
Json.NET 基本上只是调用 Activator.CreateInstance(ConverterType,ConverterParameters)
[1] 所以转换器参数被传递到转换器的构造函数中。您可以在那里记住它们并在 ReadJson()
和 WriteJson()
中使用它们,例如像这样:
public class ComponentsConverter : JsonConverter
{
public string CustomString { get; init; }
public ComponentsConverter(string customString)
{
// Remember the converter parameters for use in WriteJson() and ReadJson()
this.CustomString = customString;
}
public override bool CanConvert (Type t) => t == typeof(List<ComponentModel>);
public override void WriteJson (JsonWriter writer,object value,JsonSerializer serializer)
{
// Customize the serialized contents using the CustomString passed in to the constructor
writer.WriteValue(CustomString);
}
public override object ReadJson (JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
{
// ...
}
}
对于应用于集合项的转换器,使用 JsonPropertyAttribute.ItemConverterType
和 JsonPropertyAttribute.ItemConverterParameters
。例如:
[JsonProperty("components",ItemConverterType = typeof(ComponentConverter),ItemConverterParameters = new object [] { "custom_string_value" })]
然后:
public class ComponentConverter : JsonConverter
{
public string CustomString { get; init; }
public ComponentConverter(string customString)
{
// Remember the converter parameters for use in WriteJson() and ReadJson()
this.CustomString = customString;
}
public override bool CanConvert (Type t) => t == typeof(ComponentModel);
public override void WriteJson (JsonWriter writer,JsonSerializer serializer)
{
// ...
}
}
脚注:
[1]:我在这里过于简单化了一点。它实际上使用代码生成技术来动态生成和缓存委托,这些委托执行与 Activator.CreateInstance()
相同的事情,但没有后期绑定反射的性能损失。见例如ExpressionReflectionDelegateFactory.ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method)
。