Soap请求中的WCF XML序列化问题

时间:2016-12-21 09:33:23

标签: c# xml wcf soap

输入Xml

  <ws:processAcord xmlns:ws="http://ws.plus.predictivelogic.com/">
    <arg0>CrlUser</arg0>
    <arg1>CrlPass</arg1>
    <arg2>Life Scope</arg2>
    <arg3 />
  </ws:processAcord>

对象类

[XmlRoot(ElementName = "processAcord", Namespace = "http://ws.plus.predictivelogic.com/")]
    public class Input
    {
        //[DataMember]
        [XmlElement(ElementName = "arg0")]
        public string Arg0 { get; set; }
        //[DataMember]
        [XmlElement(ElementName = "arg1")]
        public string Arg1 { get; set; }
        //[DataMember]
        [XmlElement(ElementName = "arg2")]
        public string Arg2 { get; set; }
        //[DataMember]
        [XmlElement(ElementName = "arg3")]
        public string Arg3 { get; set; }
        //[DataMember]
        [XmlAttribute(AttributeName = "ws", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Ws { get; set; }
    }

服务定义

public UnderWritingOutput Get(Input inputXml)
{
//do stuff
}

我正在尝试从SOAPUI调用我的服务,但这会导致序列化问题。我正在调试它时,我没有在服务中获得任何数据。

我的代码必须存在一些属性声明问题,例如[DataContract]或任何其他xml属性。

  

更新1:

我已经发布了服务详情,这里是绑定..

<system.serviceModel>
<services>
  <service name="ServiceApplication.UnderWritingService" behaviorConfiguration="debug">
    <endpoint address="GetUnderWriting" binding="basicHttpBinding" contract="ServiceApplication.IUnderWritingService"></endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:60418/"/>
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>

  <serviceBehaviors>
    <behavior name="debug">
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
    </behavior>
    <behavior>
      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
  <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

当我打开soapUI请求时,它会向我显示输入xml为

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:ser="http://schemas.datacontract.org/2004/07/ServiceApplication">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:Get>
         <!--Optional:-->
         <tem:inputXml>
            <!--Optional:-->
            <ser:Arg0>?</ser:Arg0>
            <!--Optional:-->
            <ser:Arg1>?</ser:Arg1>
            <!--Optional:-->
            <ser:Arg2>?</ser:Arg2>
            <!--Optional:-->
            <ser:Arg3>?</ser:Arg3>
            <!--Optional:-->
            <ser:Ws>?</ser:Ws>
         </tem:inputXml>
      </tem:Get>
   </soapenv:Body>
</soapenv:Envelope>
  

IUnderWritingService

[ServiceContract]
    public interface IUnderWritingService
    {
        [OperationContract]
        UnderWritingOutput Get(UnderWritingInput inputXml);

    }

2 个答案:

答案 0 :(得分:1)

您的XML结构不能由DataContract序列化程序序列化,因为它不喜欢元素位于不同命名空间中的事实。如果需要该XML格式,请通过添加属性XmlSerializer

告诉WCF堆栈使用[XmlSerializerFormat]
[XmlRoot(ElementName = "processAcord", Namespace = "http://ws.plus.predictivelogic.com/")]
[XmlSerializerFormat]  // tell WCF to not to use the DataContractSerializer
public class Input
{
    [XmlElement(ElementName = "arg0", Namespace = "")]
    public string Arg0 { get; set; }
    [XmlElement(ElementName = "arg1", Namespace = "")]
    public string Arg1 { get; set; }
    [XmlElement(ElementName = "arg2", Namespace = "")]
    public string Arg2 { get; set; }
    [XmlElement(ElementName = "arg3", Namespace = "")]
    public string Arg3 { get; set; }
    [XmlAttribute(AttributeName = "ws", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Ws { get; set; }
}

以下LinqPad测试装置证明这确实呈现结果:

var xml = @"<ws:processAcord xmlns:ws=""http://ws.plus.predictivelogic.com/"">
<arg0>CrlUser</arg0>
<arg1>CrlPass</arg1>
<arg2>Life Scope</arg2>
<arg3 />
</ws:processAcord>";

var xs = new XmlSerializer(typeof(Input));
var rdr = XmlReader.Create(new StringReader(xml));
var obj = (Input) xs.Deserialize(rdr);
obj.Dump();

执行时,结果如下:

result of deserialized object

如果您更喜欢使用DataContractSerializer,则必须更改xml,以便arg0,arg1,arg2和arg3元素也位于ws命名空间中,如下所示:<ws:arg0>CrlUser</ws:arg0>

接下来要确保您的服务确实了解有效负载。您的ServiceContract应该包含命名空间:

[ServiceContract(Namespace="http://ws.plus.predictivelogic.com/"]
public interface IUnderWritingService
{
    [OperationContract]
    UnderWritingOutput Get(UnderWritingInput inputXml);

}

您没有明确说明这一点,但要注意数据合同可能是wrapped

答案 1 :(得分:-1)

您需要在Input类上放置 [DataContract] 属性以使其可序列化。此外,使用 [DataMember] 属性装饰此类的每个属性,您希望将其序列化。