C# - 在使用 WSHttpBinding 的 WS SOAP 1.2 请求中没有 POST body
C# - No POST body in WS SOAP 1.2 request with WSHttpBinding
我对 ONVIF 设备的 SOAP 1.2 请求卡住了。
我的代码是:
var c = "http://192.168.31.12:5000/onvif/device_service";
var wsBinding = new WSHttpBinding(SecurityMode.None);
wsBinding.Name = "My WSHttpBinding";
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
CustomBinding l_CustomBinding = new CustomBinding(wsBinding);
MessageEncodingBindingElement l_EncodingElement =
l_CustomBinding.Elements.Find<MessageEncodingBindingElement>();
l_EncodingElement.MessageVersion = MessageVersion.Soap12;
EndpointAddress endpointAddress = new EndpointAddress(c);
fgdfsdfsdg.ServiceReference1.DeviceClient cl = new ServiceReference1.DeviceClient(l_CustomBinding, endpointAddress);
fgdfsdfsdg.ServiceReference1.GetDeviceInformationRequest inValue = new fgdfsdfsdg.ServiceReference1.GetDeviceInformationRequest();
var Q = cl.GetDeviceInformationAsync(inValue).Result;
我在 Wireshark 中看到的内容:
POST /onvif/device_service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation"
Host: 192.168.31.12:5000
Content-Length: 261
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
WS 的期望:
POST /onvif/device_service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation"
Host: 192.168.31.12:5000
Content-Length: 261
Accept-Encoding: gzip, deflate
Connection: Close
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetDeviceInformation xmlns="http://www.onvif.org/ver10/device/wsdl"/></s:Body></s:Envelope>
我应该在我的代码中添加什么以使 C# 也发送请求 body,而不仅仅是在 HTTP POST 请求中 headers?
问题出在 header
Expect: 100-continue
来自 HttpWebRequest
。要禁用此 header 我必须添加
System.Net.ServicePointManager.Expect100Continue = false;
在我的代码之前,即我现在的代码是
var c = "http://192.168.31.12:5000/onvif/device_service";
System.Net.ServicePointManager.Expect100Continue = false;
var wsBinding = new WSHttpBinding(SecurityMode.None);
wsBinding.Name = "My WSHttpBinding";
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
CustomBinding l_CustomBinding = new CustomBinding(wsBinding);
MessageEncodingBindingElement l_EncodingElement =
l_CustomBinding.Elements.Find<MessageEncodingBindingElement>();
l_EncodingElement.MessageVersion = MessageVersion.Soap12;
解决方案在这里 https://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx/ :
Apparently I’m not the only one to run into this annoying problem.
When using the HttpWebRequest to POST form data using HTTP 1.1, it
ALWAYS adds the following HTTP header “Expect: 100-Continue”. Fixing
the problem has proved to be quite elusive.
According to the HTTP 1.1 protocol, when this header is sent, the form
data is not sent with the initial request. Instead, this header is
sent to the web server which responds with 100 (Continue) if
implemented correctly. However, not all web servers handle this
correctly, including the server to which I am attempting to post data.
I sniffed the headers that Internet Explorer sends and noticed that it
does not send this header, but my code does.
.......................
UPDATE: Lance Olson points me to the solution in my comments section.
The System.Net.ServicePointManager class has a static property named
Expect100Continue. Setting this to false will stop the header “Expect:
100-Continue” from being sent.
我对 ONVIF 设备的 SOAP 1.2 请求卡住了。
我的代码是:
var c = "http://192.168.31.12:5000/onvif/device_service";
var wsBinding = new WSHttpBinding(SecurityMode.None);
wsBinding.Name = "My WSHttpBinding";
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
CustomBinding l_CustomBinding = new CustomBinding(wsBinding);
MessageEncodingBindingElement l_EncodingElement =
l_CustomBinding.Elements.Find<MessageEncodingBindingElement>();
l_EncodingElement.MessageVersion = MessageVersion.Soap12;
EndpointAddress endpointAddress = new EndpointAddress(c);
fgdfsdfsdg.ServiceReference1.DeviceClient cl = new ServiceReference1.DeviceClient(l_CustomBinding, endpointAddress);
fgdfsdfsdg.ServiceReference1.GetDeviceInformationRequest inValue = new fgdfsdfsdg.ServiceReference1.GetDeviceInformationRequest();
var Q = cl.GetDeviceInformationAsync(inValue).Result;
我在 Wireshark 中看到的内容:
POST /onvif/device_service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation"
Host: 192.168.31.12:5000
Content-Length: 261
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
WS 的期望:
POST /onvif/device_service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetDeviceInformation"
Host: 192.168.31.12:5000
Content-Length: 261
Accept-Encoding: gzip, deflate
Connection: Close
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetDeviceInformation xmlns="http://www.onvif.org/ver10/device/wsdl"/></s:Body></s:Envelope>
我应该在我的代码中添加什么以使 C# 也发送请求 body,而不仅仅是在 HTTP POST 请求中 headers?
问题出在 header
Expect: 100-continue
来自 HttpWebRequest
。要禁用此 header 我必须添加
System.Net.ServicePointManager.Expect100Continue = false;
在我的代码之前,即我现在的代码是
var c = "http://192.168.31.12:5000/onvif/device_service";
System.Net.ServicePointManager.Expect100Continue = false;
var wsBinding = new WSHttpBinding(SecurityMode.None);
wsBinding.Name = "My WSHttpBinding";
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
CustomBinding l_CustomBinding = new CustomBinding(wsBinding);
MessageEncodingBindingElement l_EncodingElement =
l_CustomBinding.Elements.Find<MessageEncodingBindingElement>();
l_EncodingElement.MessageVersion = MessageVersion.Soap12;
解决方案在这里 https://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx/ :
Apparently I’m not the only one to run into this annoying problem. When using the HttpWebRequest to POST form data using HTTP 1.1, it ALWAYS adds the following HTTP header “Expect: 100-Continue”. Fixing the problem has proved to be quite elusive.
According to the HTTP 1.1 protocol, when this header is sent, the form data is not sent with the initial request. Instead, this header is sent to the web server which responds with 100 (Continue) if implemented correctly. However, not all web servers handle this correctly, including the server to which I am attempting to post data. I sniffed the headers that Internet Explorer sends and noticed that it does not send this header, but my code does.
.......................
UPDATE: Lance Olson points me to the solution in my comments section. The System.Net.ServicePointManager class has a static property named Expect100Continue. Setting this to false will stop the header “Expect: 100-Continue” from being sent.