Webservice returns XML 数据,C# 将值视为 null
Webservice returns XML data, C# sees the values as null
在C#中调用webservice,当响应被反序列化时,值都显示为null。
我使用 Fiddler 捕获了数据,我可以看到 XML 数据。
请求如下:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPoxpsAt2GhixHrH6i2gAkOR8AAAAAYKd3AIdbIUm9jK6F8GyWoHka0EgCtzpMpV5MZKq2eeUACQAA
</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2019-03-28T01:23:21.589Z</u:Created>
<u:Expires>2019-03-28T01:28:21.589Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-7e43c8af-1f07-42dd-89b5-6bc295e5d0f6-1">
<o:Username>username</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<CancelService xmlns="http://tempuri.org/">
<request xmlns:a="http://schemas.datacontract.org/2004/07/Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Required_Date i:nil="true"/>
<a:Service_ID>R-PMSR-19001188</a:Service_ID>
<a:Provider_Ref>Oliver_Disconnect_BB</a:Provider_Ref>
</request>
</CancelService>
</s:Body>
</s:Envelope>
响应是:
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mod="http://schemas.datacontract.org/2004/07/Models">
<soapenv:Body>
<CancelServiceResponse xmlns="http://tempuri.org/">
<CancelServiceResult>
<Status_Code>FAILED</Status_Code>
<Status_Description>Service_ID=R-PMSR-19001188 not found.</Status_Description>
<Order_ID></Order_ID>
</CancelServiceResult>
</CancelServiceResponse>
</soapenv:Body>
</soapenv:Envelope>
我运行没主意了...
编辑 1:
ServiceReference3.B2BServiceClient b2BServiceClient = new ServiceReference3.B2BServiceClient();
var elements = b2BServiceClient.Endpoint.Binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
b2BServiceClient.Endpoint.Binding = new CustomBinding(elements);
ServiceReference3.CancelRequest cancelRequest = new ServiceReference3.CancelRequest
{
Service_ID = "R-PMSR-19001188",
Provider_Ref = "Oliver_Disconnect_BB"
};
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
b2BServiceClient.ClientCredentials.UserName.UserName = "username";
b2BServiceClient.ClientCredentials.UserName.Password = "password";
ServiceReference3.Response response = b2BServiceClient.CancelService(cancelRequest);
编辑 2:除此之外,我已经看到 ExtensionData 中的值也在响应中传回。
您的消息只有三个 属性 Status_Code 、Status_Description、Order_ID 而您的响应对象有更多 属性.
WCF 按顺序反序列化消息,因此如果它在您定义 属性 的地方找不到消息中的 属性,这可能会导致空值,甚至 属性在响应消息中。
因此请在您的回复消息中按顺序包含所有 属性。
或者您可以尝试使用 DataMember 的 Order 属性 来指定模型的反序列化顺序。
[DataContract]
public class Parent
{
// IsRequired is used to test whether has received the property
// if not, it will show error. Order could change the order of the property in message
[DataMember(IsRequired = true,Order =2)]
public int Field3 { get; set; }
[DataMember(IsRequired = true,Order =1)]
public int Field1 { get; set; }
}
尝试将 Status_Code 的顺序指定为第一个,Status_Description 指定为第二个,依此类推,看看是否能解决您的问题。
终于明白问题出在哪里了。从 wsdl 生成的 Reference.cs,响应 class 的数据协定有错误的命名空间。
将其更改为:
[System.Runtime.Serialization.DataContractAttribute(Name="Response", Namespace="http://tempuri.org/")]
来自
[System.Runtime.Serialization.DataContractAttribute(Name="Response", Namespace="http://schemas.datacontract.org/2004/07/Models")]
暂时解决了这个问题。
在C#中调用webservice,当响应被反序列化时,值都显示为null。
我使用 Fiddler 捕获了数据,我可以看到 XML 数据。
请求如下:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPoxpsAt2GhixHrH6i2gAkOR8AAAAAYKd3AIdbIUm9jK6F8GyWoHka0EgCtzpMpV5MZKq2eeUACQAA
</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2019-03-28T01:23:21.589Z</u:Created>
<u:Expires>2019-03-28T01:28:21.589Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-7e43c8af-1f07-42dd-89b5-6bc295e5d0f6-1">
<o:Username>username</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<CancelService xmlns="http://tempuri.org/">
<request xmlns:a="http://schemas.datacontract.org/2004/07/Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Required_Date i:nil="true"/>
<a:Service_ID>R-PMSR-19001188</a:Service_ID>
<a:Provider_Ref>Oliver_Disconnect_BB</a:Provider_Ref>
</request>
</CancelService>
</s:Body>
</s:Envelope>
响应是:
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mod="http://schemas.datacontract.org/2004/07/Models">
<soapenv:Body>
<CancelServiceResponse xmlns="http://tempuri.org/">
<CancelServiceResult>
<Status_Code>FAILED</Status_Code>
<Status_Description>Service_ID=R-PMSR-19001188 not found.</Status_Description>
<Order_ID></Order_ID>
</CancelServiceResult>
</CancelServiceResponse>
</soapenv:Body>
</soapenv:Envelope>
我运行没主意了...
编辑 1:
ServiceReference3.B2BServiceClient b2BServiceClient = new ServiceReference3.B2BServiceClient();
var elements = b2BServiceClient.Endpoint.Binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
b2BServiceClient.Endpoint.Binding = new CustomBinding(elements);
ServiceReference3.CancelRequest cancelRequest = new ServiceReference3.CancelRequest
{
Service_ID = "R-PMSR-19001188",
Provider_Ref = "Oliver_Disconnect_BB"
};
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
b2BServiceClient.ClientCredentials.UserName.UserName = "username";
b2BServiceClient.ClientCredentials.UserName.Password = "password";
ServiceReference3.Response response = b2BServiceClient.CancelService(cancelRequest);
编辑 2:除此之外,我已经看到 ExtensionData 中的值也在响应中传回。
您的消息只有三个 属性 Status_Code 、Status_Description、Order_ID 而您的响应对象有更多 属性.
WCF 按顺序反序列化消息,因此如果它在您定义 属性 的地方找不到消息中的 属性,这可能会导致空值,甚至 属性在响应消息中。
因此请在您的回复消息中按顺序包含所有 属性。
或者您可以尝试使用 DataMember 的 Order 属性 来指定模型的反序列化顺序。
[DataContract]
public class Parent
{
// IsRequired is used to test whether has received the property
// if not, it will show error. Order could change the order of the property in message
[DataMember(IsRequired = true,Order =2)]
public int Field3 { get; set; }
[DataMember(IsRequired = true,Order =1)]
public int Field1 { get; set; }
}
尝试将 Status_Code 的顺序指定为第一个,Status_Description 指定为第二个,依此类推,看看是否能解决您的问题。
终于明白问题出在哪里了。从 wsdl 生成的 Reference.cs,响应 class 的数据协定有错误的命名空间。
将其更改为:
[System.Runtime.Serialization.DataContractAttribute(Name="Response", Namespace="http://tempuri.org/")]
来自
[System.Runtime.Serialization.DataContractAttribute(Name="Response", Namespace="http://schemas.datacontract.org/2004/07/Models")]
暂时解决了这个问题。