gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 22:55:35 26 4
gpt4 key购买 nike

编辑:澄清问题:

我已经覆盖了基类型的 JsonConverter(通过将 [JsonConverter(typeof(TConverter))] 应用于父类(super class)),但是当直接反序列化子类型时,我想使用 STANDARD 序列化(即没有自定义转换器)用于反序列化我的派生对象。如何指定在反序列化方法中使用的标准序列化,就像我没有覆盖 JsonConverter 一样?

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

但是,使用此转换器作为属性似乎也会影响所有子类,但我只希望它们使用标准转换器,这样我就不必为许多实现中的每一个都实现 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;
}
}

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

最佳答案

由于您已将 [JsonConverter(typeof(JsonProductConverted))] 直接添加到您的 Product 类型,您可以向 ProductImpl 添加一个虚拟转换器> 从 CanRead 返回 falseCanWrite :

[JsonConverter(typeof(NoConverter))]
public class ProductImpl : Product
{
}

public class NoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return false;
}

public override bool CanRead { get { return false; } }

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}

public override bool CanWrite { get { return false; } }

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

这会覆盖基类的转换器,然后退回到默认的读写序列化

样本 .Net fiddle .

另一种选择是使用 serializer.Populate() .这避免了为对象本身调用转换器:

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;
}
}

请注意,具体对象必须具有无参数构造函数才能正常工作。如果没有,您可以覆盖 protected virtual object CreateObject(Type actualType, JsonSerializer serializer, JObject json) 并通过反序列化 JObject json 中的选择属性手动调用参数化构造函数。

样本 fiddle #2 .

关于c# - 如何调用 JsonConvert.DeserializeObject 并禁用通过 [JsonConverter] 应用于基本类型的 JsonConverter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45547123/

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