2008-11-19 56 views
50

當你創建一個WCF項目時,VS.net創建一個模板。WCF中的DataContract有什麼意義?

它增加了一個類的iService1.cs文件:

// Use a data contract as illustrated in the sample below to 
// add composite types to service operations. 
[DataContract] 
public class CompositeType 
{ 
    bool boolValue = true; 
    string stringValue = "Hello "; 

    [DataMember] 
    public bool BoolValue 
    { 
     get { return boolValue; } 
     set { boolValue = value; } 
    } 

    [DataMember] 
    public string StringValue 
    { 
     get { return stringValue; } 
     set { stringValue = value; } 
    } 
} 

由於WCF服務可以返回任何用戶定義的類,爲什麼使用DataContract和CompositeType中類?

我可以返回類似:

[OperationContract] 
MyUserCollection GetUsers(); 

我缺少什麼?

+19

如果您有.NET上線的兩端,這只是罰款。如果您有一個Java客戶端調用您的服務會怎麼樣?如果將數據放入DataContracts中,則該信息將存儲在WSDL/XSD元數據中,並且也可以由.NET以外的客戶端使用。 – 2009-03-09 11:06:44

回答

51

DataContract只是一種可以在服務邊界兩側理解的類型的正式定義。

如果您返回一個「MyUserCollection」對象,您的服務的使用者將需要引用您的服務/系統的內部,這違反了SOA顯式邊界的原則。通過使用DataContract,您將以鬆散耦合的方式發佈返回類型的結構。

+2

我的WCF正在被我編寫的應用程序所使用,所以在所有實際應用中它都應該沒問題(說服SOA)。你同意嗎? – Blankman 2008-11-19 19:30:55

+1

你可能會,但你爲什麼要?添加屬性是無痛的,並且是推薦使用WCF的方式。 – 2008-11-19 19:40:31

+0

斯科特,所以我只是將MyUserCollection添加到CompositeType類和賓果遊戲! – Blankman 2008-11-19 19:44:33

26

另一個值得注意的事情是,如果您使用DataContract修飾代碼,那麼您對客戶端可以看到的內容有很多控制權,並且必須發送回您的服務。例如:

[DataContract] 
public class SampleClass 
{ 
    [DataMember(IsRequired=true)] 
    public int MyRequiredProperty { get; set; } 

    [DataMember] 
    public int MyOptionalProperty { get; set; } 

    public int MyInternalProperty { get; set; } 
} 

在上面的例子中,定義了其接收數據時,必須具有MyRequiredProperty,並且可以具有或不具有MyOptionalProperty。此外,客戶端永遠不會看到MyInternalProperty(這可以是例如一些有助於內部邏輯的屬性,但不希望它在客戶端級別暴露)。

2

我不同意那些說「DataContract只是服務邊界兩側可以理解的類型的正式定義」的海報。

這裏的關鍵字是「type」。在.NET中,類型是可以有字段,屬性和方法的對象。但是,當您在WCF服務中使用DataContract裝飾類時,結果不是魔法移植到調用代碼中的類;不是由一個長鏡頭!在調用代碼中,您將擁有一個「代理」類。代理類接收表示數據合同內容的XML。調用代碼可以通過代理類來接收這些XML值,但是而不是可以使用datacontract給調用代碼訪問類的內部裝飾。

2

爲了回答爲「marc_s」:

「如果你有.NET上 線的兩端,這只是罰款,如果你 有什麼Java客戶端調用您的 服務如果你?將您的數據放在 DataContracts中,那些存儲在WSDL/XSD元數據中的信息獲得 , 也可以由除 .NET之外的其他客戶端使用。

我認爲這是錯誤的。讓我們試着這樣做:

  1. 使用WCF 項目的默認實例與 DataContract類上 和DataMember屬性的成員類和 方法返回此類型。
  2. 建立它並顯示wsdl。 xsd包含CompositeType定義。好。
  3. 現在讓我們刪除所有屬性DataContract和DataMember
  4. 構建它並顯示wsdl。 xsd仍然包含ComposityType定義! (使用SCM軟件更明顯,這表明步驟2和步驟4之間的文件沒有區別)

因此,Java客戶端應該管理此操作,而無需Dat​​aContract和DataMember!我錯了還是什麼?

11

還有一個重要用途,您可以更改類和屬性的名稱。在序列化和反序列化過程中,這是一個方便的功能。

[DataContract(Name="EmployeeName")] 
public class Person 
{ 
    [DataMember(Name="FullName")] 
    public string Name { get; set; } 

    [DataMember(Name="HomeAddress")] 
    public string Address { get; set; } 
} 
0

也許不經常使用,我們可以使用[DataContract]來傳遞私有變量。如果不使用[DataContract]屬性,DataContractSerializer將序列化/反序列化僅公開可見的類型。

[DataContract] 
public class SampleClass 
{  
    [DataMember] 
    private int MyPrivateProperty { get; set; } 
} 

(注:如果您正在生成代理,那麼私有成員公開爲公共)