2014-01-07 74 views
1

屬性如何爲SOAP消息的屬性:如何設置SOAP格式WCF

例如我的肥皂MESSG看起來像下面

<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <a:errors i:nil="true"/> 
     <a:messages> 
      <a:MessageEntity> 
       <a:codeField>Payment Request Successful</a:codeField> 
       <a:textField i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
      </a:MessageEntity> 
     </a:messages> 
     <a:requestTrackCode>20130430T125904R14646</a:requestTrackCode> 
     <a:status i:nil="true"/> 
    </doPaymentResult> 
    </doPaymentResponse> 

,但我需要它採取的屬性不是元素的SOAP消息 像下面

<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <a:errors i:nil="true"/> 
     <a:messages> 
      <a:MessageEntity codeField="Payment Request Successful"> 
       some text here 
      </a:MessageEntity> 
     </a:messages> 
     <a:requestTrackCode>20130430T125904R14646</a:requestTrackCode> 
     <a:status i:nil="true"/> 
    </doPaymentResult> 
    </doPaymentResponse> 

我在課堂上使用datacontract。

回答

3

這是一個常見的問題 - 你想從WCF服務中返回一個對象作爲XML,但是你希望或者需要將一些或者所有的屬性值作爲XML屬性而不是XML元素來傳遞;但你不能這樣做,因爲DataContractSerializer不支持屬性(如果你已經完成了網絡搜索,你很可能會看到這個StackOverflow QA)。很可能您已經將所有WCF服務代碼遷移到了使用XmlSerializer(具有所有XmlElement/XmlAttribute/XmlType屬性等) - 並且您大聲詛咒。

嗯,我在這裏是爲了拯救你,因爲這是可能的 - 而且問題的答案實際上是從MSDN文章「數據合約序列化器支持的類型」中推斷出來的。

我要給出的例子純粹僅用於說明目的。我沒有太多時間,所以和我一起工作! •創建一個新的Asp.Net WCF服務應用程序,您可以使用Cassini作爲您的Web服務器(可能更容易 - 否則您可能必須啓用Asp.Net兼容模式)。 •打開web.config並刪除爲新服務創建的元素。 •這個例子的接口和實現模型是矯枉過正的。將[ServiceContract]和[OperationContract]聲明從爲新服務創建的接口移動到也創建的類。刪除界面。 •打開.svc標記文件並在最後添加以下內容:Factory =「System.ServiceModel.Activation.WebServiceHostFactory」 - 這將爲此服務啓用零配置WCF模型(我們將創建一個RESTful服務) 。 •以下類聲明粘貼到您的代碼隱藏SVC:

public interface IExampleData 

{ 

    string Description { get; set; } 

    string Name { get; set; } 

    int ID { get; set; } 

} 

public class ExampleData : IExampleData 

{ 

    public string Description { get; set; } 

    public string Name { get; set; } 

    public int ID { get; set; } 

} 

public class ExampleDataAttributed : ExampleData, IXmlSerializable 

{ 

    #region IXmlSerializable Members 

    public System.Xml.Schema.XmlSchema GetSchema() 

    { 

     return null; 

    } 

    public void ReadXml(System.Xml.XmlReader reader) 

    { 

     //implement if remote callers are going to pass your object in 

    } 

    public void WriteXml(System.Xml.XmlWriter writer) 

    { 

     writer.WriteAttributeString("id", ID.ToString()); 

     writer.WriteAttributeString("name", Name); 

     //we'll keep the description as an element as it could be long. 

     writer.WriteElementString("description", Description); 

    } 

    #endregion 

} 



Just to demonstrate the point, the class that will be part-serialized to attributes simply derives from one that will be serialized as normal. 


•Now add the following two methods to your service class: 
[OperationContract] 

[WebGet(UriTemplate = "/test1")] 

public ExampleData Test1() 

{ 

    return new ExampleData() { ID = 1, 
      Name = "Element-centric", 
      Description = 
"The contents of this item are entirely serialized to elements - as normal" }; 
} 


[OperationContract] 

[WebGet(UriTemplate = "/test2")] 

public ExampleDataAttributed Test2() 

{ 

    return new ExampleData_Attributed() { ID = 2, 
      Name = "Mixed", 
      Description = 
"Everything except this description will be serialized to attributes" }; 

} 

封面,烤40分鐘(即 - 建立它)。

如果你離開服務爲Service1.svc,然後運行它,並打開IE瀏覽器並瀏覽到http://本地主機:卡西尼港]/test1的

結果應該是這個樣子:

<JSLabs.ExampleData 

xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace" 

xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 

    <Description> 

     The contents of this item are entirely serialized to elements - as normal 

    </Description> 

    <ID> 

     1 

    </ID> 

    <Name> 

     Element-centric 

    </Name> 

</JSLabs.ExampleData> 

現在瀏覽到http://本地主機:[卡西尼的端口]/TEST2

<JSLabs.ExampleDataAttributed id="2" name="Mixed" 

    xmlns="http://schemas.datacontract.org/2004/07/JobServe.Labs.Web"> 

    <description>Everything except this description will be 

    serialized to attributes</description> 

</JSLabs.ExampleDataAttributed> 

它由一個小稍欠由討厭「orrible‘的xmlns =’屬性,該屬性的WCF數據c ontract序列化程序會自動穿上類型 - 但是,正如您所看到的,「ID」和「名稱」屬性確實已被推出爲屬性!

我們可以讓這兩個方法返回IExampleData,然後在該接口上使用KnownType屬性,以使其支持(根據返回的方法的代碼)。

爲了支持反序列化從屬性的對象,所有你需要做的是落實IXmlSerializable.ReadXml方法。

最後,正如前面提到的有關支持的類型的MSDN文章所述 - 您還應該能夠使用XmlElement/XmlNode類型作爲直接表示XML的方式 - DataContractSerializer就像在這種情況下一樣,採用簡短的路線並簡單獲取Xml。

,如果你的XML或JSON的客戶端的雙輸出對象這應該也不會影響到JSON格式。

Check the source of this article

+0

感謝很多基斯德維特:) – Santosh