IExtensibleDataObject 是否与 EmitDefaultValue 选项和 DataContractJsonSerializer 一起使用?

问题描述

我想设计一个 API,它接受一些通用契约,并且还可以存储扩展通用架构的附加值。看起来 IExtensibleDataObject 机器是为类似任务而构建的,它对我的​​用例很有用。

但是,当我尝试使用它时,我发现在 ExtensionDataObject 使用 EmitDefaultValue = false 选项时 DataMember 属性反序列化的奇怪行为。

考虑以下数据契约(注意Item DTO 的字段具有 EmitDefaultValue = false 选项):

[DataContract(Name = "Contract",Namespace = "")]
public class ContractGeneric : IExtensibleDataObject
{
    [DataMember(Name = "id",Order = 1)]
    public string Id;

    public ExtensionDataObject? ExtensionData { get; set; }
}

[DataContract(Name = "Contract",Namespace = "")]
public class ContractExtended
{
    [DataMember(Name = "id",Order = 1)]
    public string Id;

    [DataMember(Name = "items",Order = 2)]
    public Item[] Items;
}

[DataContract(Name = "Item",Namespace = "")]
public class Item
{
    [DataMember(Name = "code",Order = 1,EmitDefaultValue = false)]
    public string Code;

    [DataMember(Name = "name",Order = 2,EmitDefaultValue = false)]
    public string Name;
}

契约的定义对我来说看起来不错,但是从带有 ContractGenericContractExtended DTO 解析的 DataContractJsonSerializer DTO 的序列化可能会因奇怪的异常而崩溃:

Unhandled exception. System.Runtime.Serialization.SerializationException: There was an error serializing the object of type TestSerialization.ContractGeneric. Encountered unexpected el
ement local name 'code' for item in collection. 'item' is the only valid local name for elements in a collection.

例如,您可以通过以下示例获得崩溃情况:

public class Program
{
    public static void Main()
    {
        var v2 = new ContractExtended {Id = "1",Items = new[] {new Item {Code = "0"}}};
        var v2Json = ToJson(v2);
        Console.WriteLine(v2Json);
        var v1 = FromJson<ContractGeneric>(v2Json);
        var v1Json = ToJson(v1);
        Console.WriteLine(v1Json);
    }
    
    public static string ToJson<T>(T value)
    {
        using var memoryStream = new MemoryStream();
        new DataContractJsonSerializer(typeof(T)).WriteObject(memoryStream,value);
        return Encoding.UTF8.GetString(memoryStream.ToArray());
    }

    public static T FromJson<T>(string json)
    {
        using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(json));
        return (T) new DataContractJsonSerializer(typeof(T)).Readobject(memoryStream);
    }
}

看起来反序列化过程中存在错误,内部Extendedobject认为items集合的一个元素也是一个集合,但这是错误的,序列化器仅在当时检测到这种差异序列化过程。

我能否在保留 EmitDefaultValue 选项的同时避免这种奇怪的异常,并保持在 JSON 世界中(因为 XML 序列化似乎可以正确处理这种情况)。或者这是 DataContractJsonSerializer错误或某种限制?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)