使用WCF时如何为OperationContract指定名称空间?

时间:2019-11-13 18:44:01

标签: c# .net wcf soap

我正在为无法更改的服务器api创建客户端。我的客户目前产生这种格式:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <StoreSomething xmlns="urn:aaa">
      <Something>
        <SomeText xmlns="urn:bbb">My text</SomeText>
      </Something>
    </StoreSomething>
  </s:Body>
</s:Envelope>

但是,服务器希望某事位于 urn:bbb 名称空间中(即,将 xmlns 属性上移一个级别)。我该如何实现? OperationContractAttribute没有命名空间属性。

代码:

using System;
using System.ServiceModel;
using System.Xml.Serialization;

[XmlType(Namespace="urn:bbb")]
public class Something
{
    public string SomeText { get; set; }
}

[XmlSerializerFormat]
[ServiceContract(Namespace="urn:aaa")]
public interface IMyService
{
    [OperationContract]
    void StoreSomething(Something Something);
}

class Program
{
    static void Main(string[] args)
    {
        var uri = new Uri("http://localhost/WebService/services/Store");
        var factory = new ChannelFactory<IMyService>(new BasicHttpBinding(), new EndpointAddress(uri));
        IMyService service = factory.CreateChannel();

        service.StoreSomething(new Something
        {
            SomeText = "My text"
        });
    }
}

1 个答案:

答案 0 :(得分:0)

我设法通过使用unwrapped messages使它工作。不幸的是,这导致方法名称​​和参数名称都被遗漏了。因此,我不得不创建包装器类,从而导致代码混乱。

无论如何,下面是使它起作用的代码:

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [XmlSerializerFormat]
    void StoreSomething(StoreSomethingMessage message);
}

[MessageContract(IsWrapped=false)]
public class StoreSomethingMessage
{
    [MessageBodyMember(Namespace="urn:aaa")]
    public StoreSomething StoreSomething { get; set; }
}

[XmlType(Namespace="urn:bbb")]
public class StoreSomething
{
    public Something Something { get; set; }
}

public class Something
{
    public string SomeText { get; set; }
}

我还创建了一个实现IMyService并从ClientBase 继承的MyServiceClient,因为IMyService现在需要一个StoreSomethingMessage对象,但是为了简单起见,我省略了该部分。

我希望有一个更简单的解决方案。