c# - DataContractSerializer 是否仅适用于 http ://schemas. datacontract.org/2004/07/

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

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

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

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

为什么会这样,http://schemas.datacontract.org/2004/07/ 是否以某种方式进行了硬编码?为什么是这个 URL?

最佳答案

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

Basic rules regarding naming data contracts include:

  • A fully-qualified data contract name consists of a namespace and a name.
  • Data members have only names, but no namespaces.
  • When processing data contracts, the WCF infrastructure is case-sensitive to both the namespaces and the names of data contracts and data members.

A data contract namespace takes the form of a Uniform Resource Identifier (URI). The URI can be either absolute or relative. By default, data contracts for a particular type are assigned a namespace that comes from the common language runtime (CLR) namespace of that type.

By default, any given CLR namespace (in the format Clr.Namespace) is mapped to the namespace "http://schemas.datacontract.org/2004/07/Clr.Namespace". To override this default, apply the ContractNamespaceAttribute attribute to the entire module or assembly. Alternatively, to control the data contract namespace for each type, set the Namespace property of the DataContractAttribute.

并且在 Data Contract Equivalence :

For data contracts to be equivalent, they must have the same namespace and name. Additionally, each data member on one side must have an equivalent data member on the other side.

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

[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 元素本地名称和命名空间 URI 来实现:

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

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

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

关于c# - DataContractSerializer 是否仅适用于 http ://schemas. datacontract.org/2004/07/,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43051752/

相关文章:

c# - ASP.NET Web API - 驼峰式 XML

c# - Asp.net Web API 返回非描述性错误 500

c# - DBContext Builder 不包含 .NET 6 中 UseSqlServer 的定义

c# - 在 C# 中,我如何判断一个属性是否是静态的? (.Net CF 2.0)

c# - 序列化 TreeView 时丢失数据

java - 如何将使用 MPAndroidChart 库绘制的饼图中的图例居中?

c# - 将 XmlReader XML 写入 Visual Studio 中的即时窗口?

c# - 如何提高 C# 对象映射代码的性能

c# - Regex 使用 C# 将 Markdown 内联链接转换为 HTML 链接

java - XML 的 Swing GUI 生成器