ISerializable 和 JsonObject/JsonProperty JSON.NET

ISerializable and JsonObject/JsonProperty JSON.NET

我们的对象依赖于 ISerializable(为实现者标记接口可序列化)并且在内部还有 JsonObject 和 Json属性 属性。例如:

[JsonObject("Example")]
[Serializable]
public class Example : ISerializable
{
    [JsonProperty("TEST")]
    string _testString;

    public string TestString
    {
        get => _testString;
        set => _testString = value;
    }

    protected Example(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException(nameof(info), $"{nameof(info)} is null.");
        }

        _testString = info.GetString(nameof(TestString));
    }

    protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(nameof(TestString), _testString);
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException(nameof(info), $"{nameof(info)} is null.");
        }

        GetObjectData(info, context);
    }
}

那么有没有办法强制 Json 序列化程序使用 ISerializable 接口或属性。如果没有强制执行的选项,也许可以选择对不同机制进行优先排序?

更新

根据下面的一条评论,我添加了一个合同解析器,但这会导致我的序列化字符串中出现 wrong/missing 内容 - 我想我使用合同解析器的方式不对?

public class ContractResolver : IContractResolver
{
    public JsonContract ResolveContract(Type type)
    {
        if(typeof(ISerializable).IsAssignableFrom(type))
        {
            return new JsonISerializableContract(type);
        }
        return new JsonObjectContract(type);
    }
}

如果您想创建自定义逻辑,您需要通过从 DefaultContractResolver 派生来创建您的 IContractResolver。然后覆盖受保护的 CreateContract 方法而不是 ResolveContract.

例如,以下解析器将优先 ISerializable 优先于 [JsonObject] 属性(在 base implementation 中则相反)。

public class CustomContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type type)
    {
        JsonContract contract = base.CreateContract(type);
        if (!IgnoreSerializableInterface &&
            typeof(ISerializable).IsAssignableFrom(type) && 
            !(contract is JsonDictionaryContract))
        {
            return CreateISerializableContract(type);
        }
        return contract;
    }
}