2009-07-02 32 views
1

比方說,我有合同WCF如手動編寫WCF POX帖子

[ServiceContract] 
public interface IContract 
{ 
    [OperationContract] 
    [WebInvoke(Method="POST", RequestFormat=WebMessageFormat.Xml, BodyStyle=WebMessageBodyStyle.Wrapped)] 
    string ComplexPost(string name, ComplexType data); 
} 

和數據合同:

[DataContract(Name="ComplexType", Namespace="")] // don't know if those atts are req'd or not but saw them in another example 
public class ComplexType 
{ 
    public string StringData { get; set; } 
    public int IntData { get; set; } 
    public DateTime DateValue { get; set; } 
} 

我知道該請求必須被包裹在爲了有更多的比一個輸入參數,顯然你不能有一個超過一個根的XML文檔。

問題是,文檔真的很稀少,你必須包裝它。

我們的目標不是將這個與WCF一起使用,它需要作爲通用XML Web服務訪問客戶端。他們可能沒有WCF的任何知識,甚至沒有使用.NET。

很明顯,我可以從異常中得知,它期望名稱爲ComplexPost的元素(與方法名稱相同)具有名稱空間http://tempuri.org/,因爲我還沒有指定其他任何東西,所以我知道我需要這樣:

<ComplexPost xmlns="http://tempuri.org/"> 

...what exactly? 

</ComplexPost> 

的目標不是特別堅持REST原則。我沒有找到在UriTemplate中嵌入一些參數的答案,只剩下一個複雜的對象,使得Bare工作。我正在尋找一種通用的解決方案來在POST主體中包含所有數據。

使用Fiddler

發現這裏大約是什麼樣的結果將是,依據是什麼,我發現使用招。

<ComplexPost xmlns="http://tempuri.org/"> 
    <name>Value of name parameter</name> 
    <data xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <StringData>The StringData property value</StringData> 
     <IntData>10</IntData> 
     <DateValue>2009-07-07T15:38:39.7738012-05:00</DateValue> 
    </data> 
<ComplexPost> 

因此包裝元素是方法的名稱,與對您的ServiceContract指定XML命名空間,或temppuri.org如果沒有。

每個參數按順序變成一個子元素,其基本類型很容易串行化爲字符串表示形式。

我做了可空值的測試,包括一個可爲空的DateTime。顯然xmlns:i =「http://www.w3.org/2001/XMLSchema-instance」的聲明必須在需要之前出現,然後對於空值,它是一個封閉的元素,其中i:nil =「true」 ,例如

<NullableDateProperty i:nil="true" /> 

DataContract對象具有子複雜類型,甚至複雜對象的列表也很容易。

.... 
<ChildObjectPropertyName> 
    <PropertyOfChildObject>value</PropertyOfChildObject> 
    ... 
</ChildObjectPropertyName> 
<ListProperty> 
    <ObjectType> 
     <ObjectProperty>value</ObjectProperty> 
     .... 
    </ObjectType> 
    ... 
</ListProperty> 

這可能不完整,但本課肯定會讓WCF客戶端工作,然後用Fiddler檢查交換。謝謝你啦!

回答

1

如果我這樣做,發佈基於WCF的REST/POX服務,我想讓它消耗的是「任何人,任何事」我會用一個調試HTTP代理,像Fiddler2,並捕獲成功的請求會從WCF REST客戶端到WCF REST服務器。

這可以作爲文檔和示例開始的基礎,以及一組腳本測試。

還有一種方法可以打開WCF本身的消息跟蹤,但我不知道它。我總是使用小提琴手。實際上我現在打開

+0

使用Fiddler2工作得很好!我將編輯該問題以顯示我找到的內容。 – 2009-07-07 20:33:16

1

我不太明白這裏你的目標.....

「正常」 WCF服務是一個SOAP服務 - 這與其他任何講SOAP內在互操作性 - 例如Java,PHP - 你的名字。難道你不能僅僅創建你的WCF服務和伴隨的DataContract來成爲一個完整的SOAP服務並且與你的客戶進行互操作嗎?

如果沒有 - 如果你使用REST什麼將基本發生,那是你DataContract(你的服務的數據表示)將獲得序列化爲DataContractSerializer的XML。您可以輕鬆地手動在你的代碼在這個片段中測試:

DataContractSerializer dcs = new DataContractSerializer(typeof(YourDataContract)); 

FileStream outputFile = new FileStream(@"C:\output.xml"); 
dcs.WriteObject(outputFile, yourTestDataInstance); 

「yourTestDataInstance」(類型爲「YourDataContract」)的串行輸出將被寫入到C:\的Output.xml,並準備接受檢查。

當然,您可以在瀏覽到服務URL時看到REST結果。所以,你可能需要調整的結果一點 - 但你應該能夠輕鬆實現你感興趣的

在DataContract「名稱=」屬性允許您爲根元素指定不同的名稱。在XML中 - 例如如果你想「根」,而不是「YourDataContract」,用「名稱=根」屬性。

Namespace = attribute旨在允許您將數據協定放入您自己的獨立XML名稱空間 - 就像.NET命名空間一樣,它允許您消除數據歧義,使其完全獨特,並且它使確保自己的「客戶」不會從別的地方被稱爲「客戶」另一個XML元素碰撞。

兩個屬性都是可選的 - 你不必指定他們,如果你不想。

Marc