WCF XmlSerializerFormat和OperationContract:嵌套的soap参数序列化

时间:2011-09-30 07:59:58

标签: .net wcf xmlserializer operationcontract

阅读帖子XmlSerializer with specified pattern not working后,我尝试使用XmlSerializerFormat实现这样的服务:OperationContract。但是我的Soap消息包含一个附加标记,它是操作参数。如何删除该标签?

这是我的服务示例

[System.ServiceModel.ServiceContractAttribute(Namespace = "http://mynamespace.com/", ConfigurationName = "ConfigName")]
public interface MyInterfacePort
{
    [System.ServiceModel.OperationContractAttribute(Action = "http://mynamespace.com/opName", ReplyAction = "*")]
    [System.ServiceModel.FaultContractAttribute(typeof(MyError), Action = "http://mynamespace.com/opName", Name = "opErr")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    opResponse opName(opRequest request);

然后是序列化的请求:

[System.Serializable]
 public partial class opRequest
{
        public string myProperty;

生成肥皂消息:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <opName xmlns="http://mynamespace.com/">
            <request>
                <myProperty>262157</myProperty>
            </request>
        </opName>
    </s:Body>
</s:Envelope>

我的服务无法处理额外的&lt; request&gt;标签

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

如果要删除XML请求中的其他元素,可以使用 unwrapped [MessageContract]类。下面的代码显示了这种合同的例子。

public class StackOverflow_7607564
{
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://mynamespace.com/", ConfigurationName = "ConfigName")]
    public interface MyInterfacePort
    {
        [System.ServiceModel.OperationContractAttribute(Action = "http://mynamespace.com/opName", ReplyAction = "*")]
        [System.ServiceModel.FaultContractAttribute(typeof(MyError), Action = "http://mynamespace.com/opName", Name = "opErr")]
        [System.ServiceModel.XmlSerializerFormatAttribute()]
        opNameResponse opName(opNameRequest request);
    }
    public class MyError { }
    [MessageContract(IsWrapped = false)]
    public class opNameRequest
    {
        [MessageBodyMember(Name = "opName")]
        public opRequest request;
    }
    [MessageContract(IsWrapped = false)]
    public class opNameResponse
    {
        [MessageBodyMember(Name = "opNameResponse")]
        public opResponse response;
    }
    [System.Serializable]
    public partial class opRequest
    {
        public string myProperty;
    }
    [System.Serializable]
    public partial class opResponse
    {
        public string myProperty;
    }
    public class Service : MyInterfacePort
    {
        public opNameResponse opName(opNameRequest request)
        {
            return new opNameResponse { response = new opResponse { myProperty = request.request.myProperty } };
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(MyInterfacePort), new BasicHttpBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        var factory = new ChannelFactory<MyInterfacePort>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        var proxy = factory.CreateChannel();
        Console.WriteLine(proxy.opName(new opNameRequest { request = new opRequest { myProperty = "hello world" } }).response.myProperty);

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}