2010-09-27 71 views
15

我試着調用一個名爲Register的WebInvoke方法,它返回一個User對象並立即返回該對象。它看起來像如下:將名稱和名稱空間添加到DataContract是做什麼的?

User Register(User user) 
{ 
    return user; 
} 

我不知道什麼名稱和命名空間屬性調用http://localhost:8081/user/register例如當盡到DataContract屬性?

我想問的原因是因爲我最初有我的課與DataContract裝飾屬性是這樣的:

[DataContract] 
public class User 
{ 
    // Properties 
} 

當我打開了小提琴手,和發送POST請求,它表示方法不允許的,但是當我將DataContract更改爲:

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

它工作。

回答

6

這些屬性控制WSDL中元素的名稱空間和名稱。代碼中的重要部分是Namespace="":這將覆蓋默認名稱空間(http://tempuri.org)並將其值設置爲空的URL。

最後,User類將在WSDL中從http://tempuri.org/User重命名爲User。基於另一個問題和

+0

但是,它是如何工作的?我的意思是,當命名空間是http://tempuri.org/User而不是User時,爲什麼不允許使用方法? – Xaisoft 2010-09-28 16:05:58

0

我不知道什麼名稱和 命名空間屬性調用 http://localhost:8081/user/register 例如當盡到 DataContract屬性?

我建議您使用REST服務。當你沒有將Namespace設置爲空字符串而調用該服務時,是否使用命名空間xmlns =「http://tempuri.org」定義了用戶XML?如果不是你發送服務不同/未知的「數據類型」,這可能是返回錯誤的原因。

9

Johann的回答是,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

這裏有一些重要的資源... 數據合同等價=>http://msdn.microsoft.com/en-us/library/ms734767.aspx 數據協定版本管理最佳實踐=>http://msdn.microsoft.com/en-us/library/ms733832.aspx

希望這有助於。

+1

我發現最好把我的服務契約包括在一個命名空間中,並將我的數據對象放在另一個命名空間(通常只是添加'數據')後面。這是因爲基本服務名稱空間中有一些保留字,您可能會無意中碰到--methodnameResponse。 – 2010-09-30 21:10:54

14

除了其他答案之外,DataContract中的名稱空間允許在不同名稱空間中具有相同名稱的兩個對象 - 即版本控制。

這兩個對象允許在一個WSDL存​​在不同的特性,將被稱爲deserializable類型,只要它們有不同的命名空間:

[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 

在類的名字在你的項目發生了變化,但你需要支持使用現有的客戶,則可以使用這種舊的名字。

總之,名稱和命名空間屬性控制着您的對象在通過線路傳輸時如何被序列化和反序列化。當您設置它們時,您正在控制客戶端將如何看到您的數據合同。

+0

另請參閱:[DataContractAttribute.Namespace屬性的格式是什麼?](http://stackoverflow.com/q/22516894/2271552) – Gerrit 2016-03-18 13:57:07

1

除了其他答案,我會嘗試添加我所知道的這個主題。 簡而言之,它們都會用提供給這些屬性的任何內容覆蓋[DataContract]和[DataMember](Name)的默認名稱和名稱空間。 根據DataContractAttribute.Namespace屬性的MS文檔(它們被稱爲屬性的屬性,而非屬性),在「提示」部分,它指出link,「對於要成功傳輸的數據,數據的名稱在數據協定中必須在客戶端和服務端都是相同的,默認情況下,Visual Basic項目在每個文件中定義的名稱空間(稱爲「根名稱空間」,以項目命名)中添加一個前綴。導致客戶端和服務器命名空間對於相同類型不同解決方案是將名稱空間屬性設置爲「」,或顯式設置此屬性中的數據協定命名空間。 從我所瞭解的情況來看,爲了DataContract屬性能夠序列化/反序列化數據,數據在客戶端和服務器端都必須具有匹配的名稱空間,這在實際情況中可能永遠不會是這樣。例如,如果服務器端的數據以可讀和合理的方式命名,則可能位於具有類似「NameOfTheSolution.Server.NameOfTheProject」名稱的命名空間下,而在客戶端,它可能類似於「 NameOfTheSolution.Client.NameOfTheProject「。由於DataContracts所在的名稱空間不同,[DataContract]屬性將無法序列化/反序列化客戶端和服務器之間的數據。我不積極,但這可能是它說方法不允許在你的情況下,由於命名空間不匹配的原因。在名稱空間不匹配的情況下,可以在使用[DataContract]屬性時使用'Namespace'屬性,並在具有相同名稱空間的任一側(客戶端/服務器)上提供類,儘管它們物理位於不同的名稱空間中。

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

至於[DataContract]屬性的「名稱」屬性推移,它會覆蓋你提供這個屬性名稱的datacontract的名稱。在DataMember屬性的上下文中,它的一種用法是重載數據合同中的方法。 DataContract不允許具有相同名稱的兩個DataMember,因此在這種情況下,'Name'屬性非常有用。

相關問題