有没有办法从自定义 JsonConverter class 实现中访问 c​​ustomParameters object[]?

Is there a way to access customParameters object[] from within a custom JsonConverter class implementation?

我写了一个名为 CompententsConverter 的自定义 JsonConverter,它工作正常,但是我很好奇是否有办法使用替代构造函数,它采用参数对象 [] converterParameters 并传递我自己的相应地从属性自定义参数。

同样,我不确定如何实际检索 JsonConverter class 定义中的参数,或者是否可以使用 JsonConverter 属性来执行此操作。

在模型内部,具有理论参数的属性,其中 some_parameter_hereconstant 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 with 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, 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)
    {
        // ...
    }
}

小提琴演示 here and here


脚注:

[1]:我在这里过于简单化了一点。它实际上使用代码生成技术来动态生成和缓存委托,这些委托与 Activator.CreateInstance() 做同样的事情,但没有后期绑定反射的性能损失。参见例如ExpressionReflectionDelegateFactory.ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method).