1

使用 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);
}

我似乎无法弄清楚为什么会这样工作..谁能解释一下?

4

2 回答 2

0

序列化和反序列化时尝试添加 TypeNameHandling = TypeNameHandling.All

如果您有要反序列化的嵌套对象结构,这可能有助于反序列化器

于 2013-11-05T13:01:26.037 回答
0

当您说 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(),

为我测试和工作

于 2016-02-15T16:26:43.690 回答