How to generate GetSystemDateAndTime xml

末鹿安然 提交于 2020-01-09 11:58:51

问题


I have the following bit of code that i took from this source...

public bool Initialise(string cameraAddress, string userName, string password)
    {
        bool result = false;

        try
        {
            var messageElement = new TextMessageEncodingBindingElement()
            {
                MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
            };

            HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
            {
                AuthenticationScheme = AuthenticationSchemes.Digest
            };

            CustomBinding bind = new CustomBinding(messageElement, httpBinding);


            mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/Media"));
            mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
            mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;

            var profs = mediaClient.GetProfiles();

            //rest of the code...

When i run wireshark while going through the GetProfiles() part in the debugger, I see that the generated XML looks like:

What code would it take to change the xml to look like:

How am i supposed to call the GetSystemDateAndTime function?

To call the GetProfiles function, I had to create a MediaClient and, then, call that function...

Is there such thing as a MediaClient to get access to the GetSystemDateAndTime??

Edit:

I found that you could use the DeviceClient to get access the the GetSystemDateAndTime function...

You'll need to add the device management wsdl to your connected services before: https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl

I also added System.Net.ServicePointManager.Expect100Continue = false; in there because i saw someone said it helped at this link...

So i added :

CustomBinding bind = new CustomBinding(messageElement, httpBinding);
System.Net.ServicePointManager.Expect100Continue = false;
DeviceClient d = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));
var time = d.GetSystemDateAndTime();

Note: I'm still getting the error:

        ErrorMessage    "The header 'To' from the namespace 'http://www.w3.org/2005/08/addressing' was not understood by the recipient of this message, causing the message to not be processed.  This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process.  Please ensure that the configuration of the client's binding is consistent with the service's binding. "   string

回答1:


This error is saying that there is trouble when trying to read a message, so i tough it was probably due to some sort of encoding ...

AND I WAS RIGHT!!

All I had to do was changing a parameter in the TextMessageEncodingBindingElement's creation.

MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)

All you need to do is make sure that you have good encoding and AuthenticationScheme...

Here's my final code to get an onvif camera's (here cohuHD camera) system and date and time settings:

public bool Initialise(string cameraAddress, string userName, string password)
    {
        bool result = false;

        try
        {
            var messageElement = new TextMessageEncodingBindingElement()
            {
                MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)
            };

            HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
            {
                AuthenticationScheme = AuthenticationSchemes.Digest
            };

            CustomBinding bind = new CustomBinding(messageElement, httpBinding);

            System.Net.ServicePointManager.Expect100Continue = false;

            DeviceClient deviceClient = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));

            var temps = deviceClient.GetSystemDateAndTime();
        }
        catch (Exception ex)
        {
            ErrorMessage = ex.Message;
        }
        return result;
    }

Bonus:

If you want to execute a function that needs credentials, you can add those to your deviceClient like so:

//DIGEST (httpBinding)
deviceClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;

Watch out also for the EndpointAddress' URL... I think some cameras use Device_service and other device_service .



来源:https://stackoverflow.com/questions/50220574/how-to-generate-getsystemdateandtime-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!