SOAP序列化忽略对象,但在C#中包含其数据成员



我有一个现有的SOAP方法,它有大量的参数,例如

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

导致

<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>

理想情况下,我希望在不更改SOAP WSDL的情况下将这些因素考虑到一个对象中,这样代码看起来更像

[OperationContract]
public ResultObject DoSomeAction(RequestObject request)
[DataContract]
public class RequestObject
{
[DataMember]
public string a { get; set; }
...
}

然而,我似乎找不到添加属性的正确方法,只序列化请求对象的属性,而不序列化对象本身。

是否有任何方法可以定义请求对象,以使生成的SOAP最终相同?

您可以使用MessageContract而不是DataContract来执行此操作,这使您能够更好地控制消息。为了实现这一点,您还必须将结果对象包装在消息约定对象中,以获得完全相同的结果。

以下是您的对象更改为消息契约的示例。

[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; }
}

运营合同变成这样。

[OperationContract]
ResponseMessage DoSomeAction(RequestObject requestObject);

有关如何使用消息合约的更多详细信息,请查看官方文档。

由于您的评论,我还发布了对两个方法声明的请求,所以您可以看到它是相同的。

您的原件:

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

SOAP请求和响应如下所示:

<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>

而来自消息联系人的请求和响应方法让你看到的是一样的:

<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>

相关内容

最新更新