How can the same xml POSTs be getting different responses in Onvif? C#

73 Views Asked by At

I have some fairly simple code that works on one camera, but not the other.

I am simply trying to grab the time shift by using GetSystemDateAndTime() ,through a wsdl, which requires zero authentication.

I create the binding, endpoint, then create the DeviceClient. This should be all I need to send the xml request to the device and receive a response. Works perfectly fine with a reolink camera, but seems to fail on a hikvision camera. both cameras are discoverable and 100% operable through the Onvif_Device_Manager app.

public async Task<bool> Init()
        {
            try
            {
                binding = CreateBinding();
                var endpoint = new EndpointAddress(OnvifUri);
                device = new DeviceClient(binding, endpoint);
                var timeShift = await GetDeviceTimeShift(device);
                return true;
            }
            catch (Exception ex)
            {
                message = ex.Message);
                return false;
            }
        }


private static Binding CreateBinding()
        {
            
            var binding = new CustomBinding();
            var textBindingElement = new TextMessageEncodingBindingElement
            {
                MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
            };
            var httpBindingElement = new HttpTransportBindingElement
            {
                AllowCookies = true,
                MaxBufferSize = int.MaxValue,
                MaxReceivedMessageSize = int.MaxValue
            };

            binding.Elements.Add(textBindingElement);
            binding.Elements.Add(httpBindingElement);

            return binding;
        }

private static Task<TimeSpan> GetDeviceTimeShift(DeviceClient device)
        {
            return Task.Run(() =>
            {
                var utc = device.GetSystemDateAndTime().UTCDateTime;
                var dt = new System.DateTime(utc.Date.Year, utc.Date.Month, utc.Date.Day,
                                  utc.Time.Hour, utc.Time.Minute, utc.Time.Second);
                return dt - System.DateTime.UtcNow;
            });
        }

checked with wireshark and the xml in the post is correct, but the response is a 500 internal server error:

<?xml version="1.0" encoding="utf-8"?>
<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">
<GetSystemDateAndTime xmlns="http://www.onvif.org/ver10/device/wsdl" />
</s:Body>
</s:Envelope>

I sent the exact same xml through postman to the same address and got a 200 status with the correct response.

I'm not sure what I could be doing wrong. Especially since I have no problems with the same code for the reolink camera.

1

There are 1 best solutions below

0
Aaron J On

Utf-8 BOM was the bane of my existence for a day. if you notice three dots in front of your xml body that's the work of UTF-8 BOM.

Solution is as simple this when creating your text binding element for CustomBinding():

Encoding encoding = new System.Text.UTF8Encoding(false);
        var textBindingElement = new TextMessageEncodingBindingElement(MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None), encoding);

then you simply create your custom binding as usual and you are off to the races.

"BOM use is optional. Its presence interferes with the use of UTF-8 by software that does not expect non-ASCII bytes at the start of a file but that could otherwise handle the text stream."