C# 如何调用JsonConvert.DeserializeObject并通过[JsonConverter]禁用应用于基类型的JsonConverter?

C# 如何调用JsonConvert.DeserializeObject并通过[JsonConverter]禁用应用于基类型的JsonConverter?,c#,.net,json,json.net,C#,.net,Json,Json.net,编辑:澄清问题: 我已经覆盖了基类型的JsonConverter(通过对超类应用[JsonConverter(typeof(TConverter))]),但在直接反序列化子类型时,我希望使用标准序列化(即没有自定义转换器)来反序列化派生对象。如何指定在反序列化方法中使用的标准序列化,就好像我没有重写JsonConverter一样 我使用的是弹性搜索,无法使用JsonConverter的自定义实现调用JsonConvert.DeserializeObject,必须依赖弹性属性才能使用转换器 然而,

编辑:澄清问题:

我已经覆盖了基类型的JsonConverter(通过对超类应用
[JsonConverter(typeof(TConverter))]
),但在直接反序列化子类型时,我希望使用标准序列化(即没有自定义转换器)来反序列化派生对象。如何指定在反序列化方法中使用的标准序列化,就好像我没有重写JsonConverter一样

我使用的是弹性搜索,无法使用JsonConverter的自定义实现调用JsonConvert.DeserializeObject,必须依赖弹性属性才能使用转换器

然而,将此转换器用作属性似乎也会影响所有子类,但我只希望它们使用标准转换器,这样我就不必为许多实现中的每一个实现实现JsonConverter

这是我希望看到的类/逻辑:

    [Route("test")]
    [HttpPost]
    public HttpResponseMessage Test([FromBody] JToken json)
    {
        var res = json.ToObject<Product>(); // I want an object of ProductImpl type here
        return Request.CreateResponse(res); 
    }

    [JsonConverter(typeof(JsonProductConverted))]
    public abstract class Product
    {
    }

    public class ProductImpl : Product
    {
    }

    public class JsonProductConverted : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject json = JObject.Load(reader);
            //var type = GetTypeFromId((int) json["typeId"]); // Construct type from field in 
            var type = typeof(ProductImpl);
            // var res = JsonConvert.DeserializeObject(json.ToString(), type, DEFAULT_JSONCONVERTER_HERE);
            var res = DeserializeToObjectWithStandardJsonConverter(json, type);
            return res;
        }

        public override bool CanConvert(Type objectType)
        {
            return false;
        }
    }
[路线(“测试”)]
[HttpPost]
公共HttpResponseMessage测试([FromBody]JToken json)
{
var res=json.ToObject();//我在这里想要一个ProductImpl类型的对象
返回请求.CreateResponse(res);
}
[JsonConverter(typeof(JsonProductConverted))]
公共抽象类产品
{
}
公共类ProductImpl:Product
{
}
公共类JSONProductConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
JObject json=JObject.Load(读卡器);
//var type=GetTypeFromId((int)json[“typeId”]);//从中的字段构造类型
变量类型=类型(ProductImpl);
//var res=JsonConvert.DeserializeObject(json.ToString(),类型,此处为默认值\u JSONCONVERTER\u);
var res=反序列化对象和标准JSONConverter(json,类型);
返回res;
}
公共覆盖布尔CanConvert(类型objectType)
{
返回false;
}
}

如果我不提供默认的JsonConverter,或类似的,它将只使用JSONProductConverter,这将创建一个无限循环。

因为您已经将
[JsonConverter(typeof(JsonProductConverted))]
直接添加到
产品
类型中,您可以向
ProductImpl
添加一个虚拟转换器,该转换器从和返回
false

这将覆盖基类的转换器,然后在读写时都使用默认序列化

样品

另一个选择是使用。这避免了为对象本身调用转换器:

public class JsonProductConverted : JsonTypeInferringConverterBase
{
    protected override Type InferType(Type objectType, JObject json)
    {
        //var type = GetTypeFromId((int) json["typeId"]); // Construct type from field in 
        return typeof(ProductImpl);
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}

public abstract class JsonTypeInferringConverterBase : JsonConverter
{
    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    protected abstract Type InferType(Type objectType, JObject json);

    protected virtual object CreateObject(Type actualType, JsonSerializer serializer, JObject json)
    {
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(actualType);
        return contract.DefaultCreator();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var json = JObject.Load(reader);

        var actualType = InferType(objectType, json);

        // Construct object (or reuse existingValue if compatible)
        if (existingValue == null || !actualType.IsAssignableFrom(existingValue.GetType()))
        {
            existingValue = CreateObject(actualType, serializer, json);
        }

        // Populate object.
        using (var subReader = json.CreateReader())
        {
            serializer.Populate(subReader, existingValue);
        }

        return existingValue;
    }
}
请注意,具体对象必须具有无参数构造函数才能工作。如果没有,您可以重写受保护的虚拟对象CreateObject(类型actualType、JsonSerializer序列化程序、JObject json),并通过反序列化
JObject json
中的选择属性来手动调用参数化构造函数


示例。

由于您已将
[JsonConverter(typeof(JsonProductConverted))]
直接添加到您的
产品
类型,因此您可以向
产品impl
添加一个虚拟转换器,该转换器从和返回
false

这将覆盖基类的转换器,然后在读写时都使用默认序列化

样品

另一个选择是使用。这避免了为对象本身调用转换器:

public class JsonProductConverted : JsonTypeInferringConverterBase
{
    protected override Type InferType(Type objectType, JObject json)
    {
        //var type = GetTypeFromId((int) json["typeId"]); // Construct type from field in 
        return typeof(ProductImpl);
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}

public abstract class JsonTypeInferringConverterBase : JsonConverter
{
    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    protected abstract Type InferType(Type objectType, JObject json);

    protected virtual object CreateObject(Type actualType, JsonSerializer serializer, JObject json)
    {
        var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(actualType);
        return contract.DefaultCreator();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var json = JObject.Load(reader);

        var actualType = InferType(objectType, json);

        // Construct object (or reuse existingValue if compatible)
        if (existingValue == null || !actualType.IsAssignableFrom(existingValue.GetType()))
        {
            existingValue = CreateObject(actualType, serializer, json);
        }

        // Populate object.
        using (var subReader = json.CreateReader())
        {
            serializer.Populate(subReader, existingValue);
        }

        return existingValue;
    }
}
请注意,具体对象必须具有无参数构造函数才能工作。如果没有,您可以重写受保护的虚拟对象CreateObject(类型actualType、JsonSerializer序列化程序、JObject json),并通过反序列化
JObject json
中的选择属性来手动调用参数化构造函数


示例。

请尝试制定一个清晰的问题,很难得到你想要的。请尝试制定一个清晰的问题,很难得到你想要的。这100%有效。允许在弹性搜索中保存抽象类,然后非常容易地将它们反序列化为真实对象,这使得即使对于具有大量实现的抽象对象也非常简单。非常感谢。这非常好,但我需要在我的具体类中添加一个私有json构造函数,以使它们正确地反序列化。。如果能得到一个完整的解释(或链接)那就太好了,因为我现有的知识并没有扩展到这一点,我永远也不会把这个解决方案的效率提高到100%。允许在弹性搜索中保存抽象类,然后非常容易地将它们反序列化为真实对象,这使得即使对于具有大量实现的抽象对象也非常简单。非常感谢。这非常好,但我需要在我的具体类中添加一个私有json构造函数,以使它们正确地反序列化。。如果能得到一个完整的解释(或链接)那就太好了,因为我现有的知识并没有扩展到这个方面,我永远也不会想出这个解决方案