簡體   English   中英

如何自定義WCF XML序列化

[英]How to customize WCF XML serialization

我們有一個現有的SOAP Web服務接口,我們想使用WCF來實現新的應用程序。 除了一個小細節,這似乎工作正常。 函數的返回類型的XML名稱空間必須與Web服務本身的XML名稱空間不同。 為了我的一生,我無法使它運轉。

我已經用一個小樣本項目重新創建了同樣的問題。 WCF接口:

[XmlSerializerFormat]
[ServiceContract(Namespace = "urn:outer-namespace")]
public interface IService1
{
    [OperationContract]
    MyClass DoStuff(int value);
}

[Serializable]
public class MyClass
{
    [XmlElement(ElementName = "DataString")]
    public string MyString { get; set; }
}

Web服務實現:

    public class Service1 : IService1
{
    public MyClass DoStuff(int value)
    {
        return new MyClass { MyString = "Wooh!" };
    }
}

然后將該Web服務的響應序列化為:(省略SOAP內容)

  <DoStuffResponse xmlns="urn:outer-namespace">
     <DoStuffResult>
        <DataString>Wooh!</DataString>
     </DoStuffResult>
  </DoStuffResponse>

但是我們希望<DoStuffResult>是xmlns =“ urn:inner-namespace”。

我嘗試在接口函數或Web服務函數上添加[return:XmlElement(...)],但這不是必須的。 另外,MyClass類定義上的[XmlType]或[XmlRoot]無效。

有誰知道如何更改對象的序列化XML名稱空間(或元素名稱),該對象是WCF Web服務功能的返回值?

使用XML序列化(或更好)數據協定定義屬性定義名稱空間。

例如,使用XML序列化:

[Serializable, XmlRoot(namespace="http://example.com/eg1")]
public class MyClass {
  [XmlElement(ElementName = "DataString")]
  public string MyString { get; set; }
}

例如,使用數據合同序列化:

[DataContract(Namespace="http://example.com/eg2")]
public class MyClass {
  [DataMember]
  public string MyString { get; set; }
}

編輯

基於第一個注釋,以上內容將不起作用,因為我們希望在消息周圍的SOAP包裝上設置名稱空間,而不是消息本身。

OperationContractAttribute提供對名稱空間的控制,並且在方法級別上看不到任何其他WCF屬性。

兩種可能性:(1)通過降低抽象級別並使用消息契約,您可能具有足夠的控制權。 (2)獲取該服務的當前WSDL(使用svcutil.exe ),手動對其進行調整以獲取所需的名稱空間,然后再次使用svcutil.exe生成代碼,並查看生成的代碼。

經過數天的搜索並嘗試了數十種推薦的解決方案; 我終於能夠使WCF停止強制將Result附加到Web服務方法的名稱的包裝容器名稱。 技巧是將以下裝飾器屬性添加到Web服務接口:

[return:MessageParameter(Name = "whatIWantItNamed")]

該屬性應直接放置/放置在接口中的[OperationContract]屬性之后(並在實際方法存根之前)。

(我還需要將XmlSerializerFormat屬性添加到所有ServiceContractOperationContract屬性。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM