使用 Json.NET 反序列化保存的接口对象而不定义其实现类型会抛出错误(当然),所以我编写了一个可重用的类:
public class MakeJsonConverter<TParent, TChild> : JsonConverter where TChild:TParent
{
private readonly Type _parent;
private Type _child;
public MakeJsonConverter()
{
_parent = typeof(TParent);
_child = typeof(TChild);
}
public override bool CanConvert(Type objectType)
{
return (objectType == _parent);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<TChild>(reader);
}
//This should never be called. Only reading from saved interface data was an issue without using a converter.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
它工作正常,除了我传递给它的设置似乎没有被使用。实际上我不确定,我所知道的是MissingMemberHandling.Error不起作用。
public virtual string SerializeWithConverter<TParent, TChild>(TParent obj) where TChild : TParent
{
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new DefaultContractResolver
{
DefaultMembersSearchFlags =
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
},
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
//Settings important to this situation
MissingMemberHandling = MissingMemberHandling.Error,
Converters = new List<JsonConverter> { new MakeJsonConverter<TParent, TChild>() }
};
return JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
}
我似乎无法弄清楚为什么这是这样工作的......任何人都可以解释吗?
尝试添加 TypeNameHandling = TypeNameHandling。All 在序列化和反序列化时
如果您有要反序列化的嵌套对象结构,这可能有助于反序列化程序
当你说 MissingMemberHandling.Error 不起作用时,你到底是什么意思?我假设这是因为当用户过度/不足发布与您的对象不匹配的对象时,您预计会出现错误?无论哪种方式,我相信当您设置自己的自定义ContractResolver时,MissingMemberHandling.Error不会抛出。相反,请创建自己的类,该类继承自 DefaultContractResolver 并重写 JsonObjectContract。这将提供类似于您期望的结果。
public class CustomContractResolver : DefaultContractResolver
{
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
var contract = base.CreateObjectContract(objectType);
contract.ItemRequired = Required.Always;
return contract;
}
}
然后将其用作合同解析器
ContractResolver = new CustomContractResolver(),
为我测试并工作