编辑:澄清问题:
我已经覆盖了JsonConverter的基类型(通过将[JsonConverter(typeof(TConverter))]
应用于超类),但是当直接反序列化子类型时,我想使用STANDARD序列化(即没有自定义转换器)来反序列化我的派生对象。如何在反序列化方法中指定STANDARD序列化,就像我没有覆盖JsonConverter一样?
我正在使用弹性搜索,无法使用我自定义的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转换器,这会产生一个无限循环。
答案 0 :(得分:2)
由于您已将[JsonConverter(typeof(JsonProductConverted))]
直接添加到Product
类型,因此您可以向ProductImpl
添加一个虚拟转换器,该转换器会从CanRead
和{{{{}}返回false
3}}:
[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();
}
}
这会覆盖基类的转换器,然后回退到读取和写入的默认序列化
示例CanWrite
。
另一种选择是使用.Net fiddle。这样可以避免对转换器调用对象本身:
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
内的选择属性来手动调用参数化构造函数。