Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

c# - How to generate GetSystemDateAndTime xml

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:

xml0

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

xml1

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 .


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...