2 回答
TA贡献1934条经验 获得超2个赞
正如在解释这个答案,以parse.com:SerializationException反序列化JSON与“__type”属性的对象,你的问题是,"__type"是一个保留的属性的DataContractJsonSerializer。它用于识别多态类型的派生类型。从文档:
保留类型信息
为了保留类型标识,在将复杂类型序列化为 JSON 时,可以添加“类型提示”,并且反序列化器会识别该提示并采取适当的行动。“类型提示”是一个 JSON 键/值对,键名为“__type”(两个下划线后跟单词“type”)。该值是“DataContractName:DataContractNamespace”形式的 JSON 字符串(第一个冒号之前的任何内容都是名称)...
类型提示与 XML Schema Instance 标准定义的 xsi:type 属性非常相似,并在序列化/反序列化 XML 时使用。
由于与类型提示的潜在冲突,禁止名为“__type”的数据成员。
因此,您无法手动将此属性添加到您的类中并使其正确翻译。
但是,您可以利用序列化程序对多态性的处理来"__type" 自动读取和写入,方法是定义一个Region类继承自某个基类型的区域的类层次结构,例如RegionBase,由 引用Country.Parent:
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Country
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string GeoType { get; set; }
[DataMember]
public RegionBase Parent { get; set; }
[DataMember]
public string RegionID { get; set; }
[DataMember]
public string CountryCode { get; set; }
[DataMember]
public string ISO { get; set; }
}
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
[KnownType(typeof(Region))]
public class RegionBase
{
}
[DataContract(
Name = "Region",
Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Region : RegionBase
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string GeoType { get; set; }
[DataMember]
public string Code { get; set; }
}
然后反序列化为 a List<Country>,因为您的外部 JSON 容器是一个数组。
笔记:
类型提示的格式为"DataContractName:DataContractNamespace".
此外,如减少类型提示的大小中所述,类型提示中的前缀#是http://schemas.datacontract.org/2004/07/. 因此Region必须具有以下数据合约名称:
[DataContract(
Name = "Region",
Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
我的答案中的类型层次结构足以反序列化示例 JSON,但它可能并不理想。例如,在实践中,可能存在RegionBase与Region(例如ID)共享属性的其他子类型,因此应该将这些属性移至基类。或者可能还有其他可能的子类RegionBase未在您的问题中显示,例如"SomeOtherKindOfRegion:#MEDEX.Library.Geo",需要将其添加到模型中。
由于这个 JSON 似乎来自 WCF 服务,因此希望它已经发布了它的Service Metadata。如果是这样,它将允许您使用Visual Studio 中的添加服务引用自动生成客户端。有关如何执行此操作的说明,请参阅如何:创建 Windows Communication Foundation 客户端和如何:添加、更新或删除服务引用。自动客户端生成应该避免您遇到的困难。
有关这方面的示例,请参阅如何使用 DataContractSerializer 使用未命名的类型集合反序列化 JSON或如何使用 WSDL 文件创建 WCF 服务(不进行调用)。
数据契约序列化程序必须RegionBase通过已知类型机制获知所有可能的多态子类型。
- 2 回答
- 0 关注
- 237 浏览
添加回答
举报