【问题标题】:Does DataContractSerializer work only with http://schemas.datacontract.org/2004/07/DataContractSerializer 是否仅适用于 http://schemas.datacontract.org/2004/07/
【发布时间】:2017-03-27 16:29:30
【问题描述】:

我遇到了一个问题,即我的对象没有从 Post 请求的正文中反序列化,我按照 this answer 说明,因为 WebApi 中默认使用 DataContractSerializer,您需要以这种方式定义您的 xmlns

p>
<TestModel 
xmlns="http://schemas.datacontract.org/2004/07/YourMvcApp.YourNameSpace">

确实可以,但是如果我更改年份或月份,例如http://schemas.datacontract.org/2005/07/...,它就会停止工作,并且我的对象再次变为空。

这是为什么,http://schemas.datacontract.org/2004/07/ 是否以某种方式硬编码?为什么是这个网址?

【问题讨论】:

    标签: c# xml asp.net-web-api datacontractserializer


    【解决方案1】:

    每个数据合约对象都由一个完全限定的数据合约名称标识。如Data Contract Names 中所述:

    关于命名数据​​合约的基本规则包括:

    • 完全限定的数据协定名称由命名空间和名称组成。
    • 数据成员只有名称,没有命名空间。
    • 在处理数据协定时,WCF 基础结构对命名空间以及数据协定和数据成员的名称都区分大小写。

    数据协定命名空间采用统一资源标识符 (URI) 的形式。 URI 可以是绝对的或相对的。默认情况下,为特定类型的数据协定分配一个命名空间,该命名空间来自该类型的公共语言运行时 (CLR) 命名空间。

    默认情况下,任何给定的 CLR 命名空间(格式为 Clr.Namespace)都映射到命名空间“http://schemas.datacontract.org/2004/07/Clr.Namespace”。要覆盖此默认值,请将ContractNamespaceAttribute 属性应用于整个模块或程序集。或者,要控制每种类型的数据协定命名空间,请设置DataContractAttributeNamespace 属性。

    Data Contract Equivalence:

    为了使数据合约等效,它们必须具有相同的命名空间和名称。此外,一侧的每个数据成员必须在另一侧具有等效的数据成员。

    因此,要通过网络成功发送数据合约对象,完全限定的数据合约名称必须在两端匹配。如上所述,默认数据协定命名空间是 http://schemas.datacontract.org/2004/07/Clr.Namespace,但您可能希望更改它以以某种方式反映您的组织,例如:

    [DataContract(Namespace = "http://schemas.MyOrganization.com/v1")]
    public class TestModel 
    {
        [DataMember]
        public string Value { get; set; }
    }
    

    或者您可以为整个程序集和 .Net 命名空间设置它:

    [assembly: ContractNamespace("http://schemas.MyOrganization.com/v1", ClrNamespace = "YourMvcApp.YourNameSpace")]
    

    数据合约序列化可用于 JSON 和 XML,那么DataContractSerializer 如何将数据合约名称从 XML 映射到 XML?它使用 XML 元素本地名称和命名空间 URI:

    <TestModel xmlns="http://schemas.datacontract.org/2004/07/YourMvcApp.YourNameSpace">
    

    xmlns="http://schemas.datacontract.org/2004/07/YourMvcApp.YourNameSpace" 属性是本地名称为TestModel 的元素的default XML namespace declaration。本地名称和命名空间共同构成元素的expanded name。如果命名空间 URI 和本地名称匹配,则认为 XML 元素名称相等,因此 Microsoft 选择将数据协定名称对应于 XML 元素本地名称,并将数据协定命名空间对应于 XML 命名空间 URI,这就是为什么要更改 即使是 URI 中的年份或月份也会导致反序列化失败。

    因此,如您所见,命名空间的选择需要在推出数据协定 Web API 或 WCF 服务之前确定,因为更改命名空间需要在客户端更新命名空间。 (当然,对于 WCF,客户端通常会按照说明从架构元数据自动生成客户端,例如 herehere。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      • 2017-11-17
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多