2009-08-18 46 views
2

的設置如何接受一個基本類型的集合WCF

我有一個公開基本類型(如動物),以及一些派生類型的WCF服務(如獅子,老虎,和熊)。另一種類型(例如Zoo)包含一個屬性,該屬性是基類型的集合。基本類型是具體的,不是抽象,所以集合包含基本類型和/或派生類型(以任意組合)的實例是完全可以接受的。例如:

[DataContract, KnownType(typeof(Lion)), 
KnownType(typeof(Tiger)), KnownType(typeof(Bear))] 
public class Animal 
{ 
    [DataMember] 
    public string Species { get; set; } 
} 

[DataContract] 
public class Lion : Animal { } 


[DataContract] 
public class Tiger : Animal { } 


[DataContract] 
public class Bear : Animal { } 

[DataContract] 
public class Zoo 
{ 
    [DataMember] 
    public List<Animal> Animals { get; set; } 
} 

我的一個服務操作的接受這種類型作爲參數,像這樣:

[ServiceContract] 
public interface IZooService 
{ 
    [OperationContract] 
    void SetZoo(Zoo zoo); 
} 

所有這一切都很好,並且發出的WSDL看起來完全沒有給我。它包含所有類型並正確指示派生類型從基類型繼承。所以,我應該能夠使用SOAP消息來調用我的服務,如下列:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:z="http://zoo.org"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <z:SetZoo> 
     <z:Zoo> 
      <z:Animals> 
       <z:Animal> 
        <z:Species>Crocodile</z:Species> 
       </z:Animal> 
       <z:Tiger> 
        <z:Species>Bengal</z:Species> 
       </z:Tiger> 
       <z:Bear> 
        <z:Species>Grizzly</z:Species> 
       </z:Bear> 
      </z:Animals> 
     </z:Zoo> 
     </z:SetZoo> 
    </soapenv:Body> 
</soapenv:Envelope> 

在上面的SOAP消息中,動物集合包含底座動物類型的一個實例,派生虎的一個實例類型以及派生Bear類型的實例。 WCF應該能夠成功地反序列化此消息。

當它接收到上述消息的問題

WCF不會引發任何異常。相反,它完全忽略派生類型(Tiger和Bear),並且在反序列化消息傳遞給我的代碼時,Animals集合只包含Crocodile條目,因爲它是基類型的。

所以,我想我有兩個問題......首先,爲什麼WCF不反序列化集合中的派生類型實例。第二,由於WCF顯然不喜歡這個SOAP消息,爲什麼它不拋出異常呢?這種無聲失敗令人非常困擾。

回答

6

好吧......我找到了問題所在。事實證明,這種情況下的SOAP語法需要一些額外的工作才能正確使用。由於Animals集合被定義爲Animal類型的數組,所以SOAP消息中的所有子元素都必須是元素,即使它們實際上是派生類型的實例。實際的實例類型由「type」屬性定義,該屬性是XMLSchema實例名稱空間的一部分。所以,我的SOAP消息應該是這個樣子的:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://zoo.org"> 
<soapenv:Header/> 
<soapenv:Body> 
    <z:SetZoo> 
    <z:Zoo> 
     <z:Animals> 
      <z:Animal> 
       <z:Species>Crocodile</z:Species> 
      </z:Animal> 
      <z:Animal i:type="z:Tiger"> 
       <z:Species>Bengal</z:Species> 
      </z:Animal> 
      <z:Animal i:type="z:Bear"> 
       <z:Species>Grizzly</z:Species> 
      </z:Animal> 
     </z:Animals> 
    </z:Zoo> 
    </z:SetZoo> 
</soapenv:Body> 
</soapenv:Envelope> 

當然,這還是如果它不理解SOAP消息並沒有解決我的其他的關注,這就是WCF解串器應該拋出一個異常。它不應該默默地忽略部分信息!

+0

非常好,謝謝!我幾乎崩潰試圖用肥皂用戶界面創建一個適當的消息... – juarola 2012-03-04 12:27:21

+0

我認爲WCF解串器不會忽略部分消息是麻煩的。這會迫使你始終保持客戶端和服務器的同步,而不一定是一個理想的特性。 – Jeff 2012-12-11 18:20:55

相關問題