简体   繁体   中英

SOAP serialization ignoring object but including its data members in C#

I have an existing SOAP method which has a huge number of parameters, eg

[OperationContract]
public ResultObject DoSomeAction(string a, string b, DateTime c, OtherEnum d, 
     string e, string f, ....)

Which results in

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <DoSomeAction>
         <xs:element minOccurs="0" maxOccurs="1" name="a" type="xs:string"/>
         ...
      </DoSomeAction>
   </soapenv:Body>
</soapenv:Envelope>

Ideally I'd like to factor out these into an object without changing the SOAP WSDL, so that the code could look more like

[OperationContract]
public ResultObject DoSomeAction(RequestObject request)

[DataContract]
public class RequestObject
{
    [DataMember]
    public string a { get; set; }
    ...
}

However I can't seem to find the correct way to add an attribute to serialize only the properties of Request Object and not the object itself.

Are there any way to define the Request Object that that the resulting SOAP will end up the same?

You can do this using MessageContract instead of DataContract this gives you more control over the message. For this to work you have to also wrap the result object in a message contract object to get exactly the same.

Here is a sample of your objects changed to message contracts.

[MessageContract(WrapperName="DoSomeActionResponse")]
public class ResponseMessage
{
   [MessageBodyMember(Name="DoSomeActionResult")]
   public ResultObject ResultObject { get; set; }
}

[MessageContract(WrapperName = "DoSomeAction")] // renames the element to DoSomeAction 
public class RequestObject
{
   [MessageBodyMember]
   public string a { get; set; }
   [MessageBodyMember]
   public string b { get; set; }
   [MessageBodyMember]
   public DateTime c { get; set; }
   [MessageBodyMember]
   public int d { get; set; }
   [MessageBodyMember]
   public string e { get; set; }
   [MessageBodyMember]
   public string f { get; set; }
}

And the operation contract becomes like this.

[OperationContract]
ResponseMessage DoSomeAction(RequestObject requestObject);

For more details on how to use message contracts check also the official documentation .

Due to your comment I post also the requests for both method declaration so you see it is the same.

Your original:

[OperationContract]
ResultObject DoSomeAction(string a, string b, DateTime c, int d, string e, string f);

And the SOAP request and response look like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/DoSomeAction</Action>
  </s:Header>
  <s:Body>
    <DoSomeAction xmlns="http://tempuri.org/">
      <a i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <b i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <c>2020-04-05T02:04:00</c>
      <d>0</d>
      <e i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <f i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
    </DoSomeAction>
  </s:Body>
</s:Envelope>

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <DoSomeActionResponse xmlns="http://tempuri.org/">
      <DoSomeActionResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:ResultValue>12</a:ResultValue>
      </DoSomeActionResult>
    </DoSomeActionResponse>
  </s:Body>
</s:Envelope>

And the request and response from the message contact methods so you see it is the same:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/DoSomeAction</Action>
  </s:Header>
  <s:Body>
    <DoSomeAction xmlns="http://tempuri.org/">
      <a i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <b i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <c>2020-04-05T02:03:00</c>
      <d>0</d>
      <e i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <f i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
    </DoSomeAction>
  </s:Body>
</s:Envelope>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <DoSomeActionResponse xmlns="http://tempuri.org/">
      <DoSomeActionResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfService2" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:ResultValue>11</a:ResultValue>
      </DoSomeActionResult>
    </DoSomeActionResponse>
  </s:Body>
</s:Envelope>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM