向DataContract添加名称和命名空间有什么作用?

我尝试调用一个名为Register的WebInvoke方法,该方法返回一个User对象并立即返回该对象。 它看起来如下:

User Register(User user) { return user; } 

我不确定在调用http:// localhost:8081 / user / register时,Name和Namespace属性对DataContract属性的作用是什么?

我问的原因是因为我最初使用DataContract属性装饰了我的类,如下所示:

 [DataContract] public class User { // Properties } 

当我打开Fiddler并发送一个Post请求时,它说方法不允许,但当我将DataContract更改为:

 [DataContract(Name="User", Namespace="")] 

有效。

这些属性控制WSDL中元素的名称空间和名称。 代码中的重要部分是Namespace="" :这将覆盖默认命名空间(http://tempuri.org)并将其值设置为空URL。

最后,User类将在WSDL中从http://tempuri.org/User重命名为User。

除了其他答案之外,DataContract中的命名空间允许在不同的命名空间中使用两个相同名称的对象 – 即版本控制。

允许这两个对象作为WSDL中的不同属性存在,并且只要它们具有不同的名称空间,它们就是已知的可反序列化类型:

 [DataContact(Namespace = "http://myservice/v1/thing")] V1.Thing [DataContact(Namespace = "http://myservice/v2/thing")] V2.Thing 

当然,它们需要存在于您的C#代码中以使其有效。 或者,您也可以使用“名称”属性更改对象已知的名称。

 [DataContact(Name = "Thing")] V1.Thing [DataContact(Name= = "newThing")] V2.Thing 

您可以在项目中更改类名称时使用此选项,但需要支持使用“旧”名称的现有客户端。

总之,Name和Namespace属性控制在通过线路传输时对象的序列化和反序列化方式。 设置它们时,您将控制客户端查看数据协定的方式。

约翰的答案,IMO是正确的。

它以这种方式工作,因为当您发送SOAP消息时,元素需要是名称空间限定的,否则WCF不知道如何将SOAP反序列化为用户数据协定,因为名称空间不匹配。

在C#中,这两个对象是不同的,因为它们位于不同的命名空间中……

 namespace UserServices { public class User { public string FirstName { get; set; } } } namespace TempuriServices { public class User { public string FirstName { get; set; } } } 

XML / SOAP中的命名空间用于相同的目的,以确保对象来自相同的“主体”/“公司”/“组织”/“域”等。

根据我的发现,当我构建SOAP服务时,我倾向于将所有数据契约,服务契约和绑定名称空间保留在同一名称空间中,例如“ http://mycompany.com/services/serviceName

这里有一些很棒的资源…… Data Contract Equivalence => http://msdn.microsoft.com/en-us/library/ms734767.aspx Data Contract Versioning Best Practices => http://msdn.microsoft.com/en -us /库/ ms733832.aspx

希望这可以帮助。

除了其他答案,我将尝试添加我对此主题的了解。 简而言之,它们都会覆盖[DataContract]和[DataMember](Name)的默认名称和命名空间,无论您提供给这些属性。 根据MS的DataContractAttribute.Namespace属性文档(它们被称为属性的属性,而不是属性),在’Tip’部分,它表示链接 ,“为了成功传输数据,数据中的数据名称客户端和服务器中的契约必须相同。默认情况下,Visual Basic项目为每个文件中定义的命名空间添加一个前缀(称为“根命名空间”,以项目命名)。添加此前缀会导致客户端和服务器名称空间对于相同类型是不同的。 解决方案是将Namespace属性设置为“” ,或者在此属性中显式设置数据协定名称空间。“ 根据我的理解,对于DataContract属性能够序列化/反序列化数据,数据必须在客户端和服务器端都具有匹配的命名空间,在现实世界中可能总是不是这种情况。 例如,如果以可读和合理的方式命名,那么服务器端的数据可能位于名称类似于“NameOfTheSolution.Server.NameOfTheProject”的名称空间下,而在客户端,它可能类似于“ NameOfTheSolution.Client.NameOfTheProject“。 由于DataContracts所在的命名空间不同,[DataContract]属性将无法序列化/反序列化客户端和服务器之间的数据。 我不是肯定的,但这可能是因为命名空间不匹配导致你的方法不允许使用方法的原因。 在命名空间不匹配的情况下,可以在使用[DataContract]属性时使用“Namespace”属性,并在任一侧(客户端/服务器)提供具有相同命名空间的类,尽管它们实际上位于不同的命名空间中。

 [DataContract (Namespace = “Whatever you want, usually uri”)] public class User {} 

就[DataContract]属性的’Name’属性而言,它会使用您为此属性提供的名称覆盖datacontract的名称。 在DataMember属性的上下文中,它的一个用途是重载数据协定中的方法。 DataContract不允许两个具有相同名称的DataMember,因此在这种情况下,“Name”属性很有用。

根据另一个问题和:

我不确定在调用http:// localhost:8081 / user / register时,Name和Namespace属性对DataContract属性的作用是什么?

我建议您使用REST服务。 当您在未将Namespace设置为空字符串的情况下调用服务时,您是否使用名称空间xmlns =“http://tempuri.org”定义了User XML? 如果没有,你发送服务不同/未知“数据类型”,这可能是返回错误的原因。