问题
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