海康开放平台海康威视合作生态致力打造一个能力开放体系、两个生态圈,Hikvision AI Cloud开放平台是能力开放体系的核心内容。它是海康威视基于多年在视频及物联网核心技术积累之上,融合AI、大数据、云计算等技术,为合作伙伴提供的一个二次开发及创新的平台。https://open.hikvision.com/docs/docId?productId=5c67f1e2f05948198c909700&version=%2Ff95e951cefc54578b523d1738f65f0a1&curNodeId=a0f95defa04344f8b3582eb839eccf70
public class HIKOpenAPI
{
public static string HttpPost(string url,string api, string body, string ak, string sk) {
Log.Logs("user", Log.LogType.Info, $"Send|| url(api).{url + api}");
Log.Logs("user", Log.LogType.Info, $"Send|| body.{body}");
var headers = new Dictionary { { "Accept", "*/*" }, { "Content-Type", "application/json" } };
var request = new Request(Method.POST_STRING, url, api, ak, sk, 10000) {
Headers = headers,
SignHeaderPrefixList = null,
Querys = null,
StringBody = body
};
var result= DoPoststring(request.Host, request.Path, request.Timeout, request.Headers, request.Querys, request.StringBody, request.SignHeaderPrefixList, request.AppKey, request.AppSecret, false);
Log.Logs("user", Log.LogType.Info, $"Recv|| result.{result}");
return result;
}
//Post请求方法
public static string DoPoststring(string host, string path, int connectTimeout, Dictionary headers,
Dictionary querys, string body, List signHeaderPrefixList, string appKey,
string appSecret, bool autoDown)
{
try
{
headers = initialBasicHeader("POST", path, headers, querys, null, signHeaderPrefixList, appKey,
appSecret);
ServicePointManager.ServerCertificateValidationCallback =
RemoteCertificateValidate;
//验证服务器证书回调自动验证
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(initUrl(host, path, querys));
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
//设置HTTP协议的并发连接数
//ServicePointManager.DefaultConnectionLimit = 512;
//关闭重定向
request.AllowAutoRedirect = false;
request.Method = "POST";
request.Timeout = connectTimeout;
string accept = headers["Accept"];
request.Accept = accept;
string contentType = headers["Content-Type"];
request.ContentType = contentType;
foreach (string headerKey in headers.Keys)
{
if (headerKey.Contains("x-ca-"))
{
request.Headers.Add(headerKey + ":" +
(string.IsNullOrWhiteSpace(headers[headerKey]) ? "" : headers[headerKey]));
}
if (headerKey.Equals("tagId"))
{
request.Headers.Add(headerKey + ":" +
(string.IsNullOrWhiteSpace(headers[headerKey]) ? "" : headers[headerKey]));
}
}
if (!string.IsNullOrWhiteSpace(body))
{
byte[] postBytes = Encoding.UTF8.GetBytes(body);
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
}
var response = (HttpWebResponse) request.GetResponse();
var result = "";
if (response.StatusCode != HttpStatusCode.OK) return result;
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
return result;
}
catch (Exception ex)
{
return new {code="404",msg= ex.Message }.Json();
}
}
//获取当时时间戳
public static long GetTimestamp(DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
long t = (time.Ticks - startTime.Ticks)/10000; //除10000调整为13位
return t;
}
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain,
SslPolicyErrors error)
{
//为了通过证书验证,总是返回true
return true;
}
public static Dictionary initialBasicHeader(string method, string path,
Dictionary headers, Dictionary querys, Dictionary bodys,
List signHeaderPrefixList, string appKey, string appSecret) //throws MalformedURLException
{
if (headers == null)
{
headers = new Dictionary();
}
headers["x-ca-timestamp"] = GetTimestamp(DateTime.Now).ToString();
//headers["x-ca-nonce"] = "5d1b5861-2e04-4bdc-ab02-d393acc6e8df";
headers["x-ca-nonce"] = System.Guid.NewGuid().ToString();
headers["x-ca-key"] = appKey;
headers["x-ca-signature"] = sign(appSecret, method, path, headers, querys, bodys, signHeaderPrefixList);
return headers;
}
public static string initUrl(string host, string path, Dictionary querys)
//throws UnsupportedEncodingException
{
StringBuilder sbUrl = new StringBuilder();
sbUrl.Append(host);
if (!string.IsNullOrWhiteSpace(path))
{
sbUrl.Append(path);
}
if (null != querys)
{
StringBuilder sbQuery = new StringBuilder();
foreach (string queryKey in querys.Keys)
{
if (0 < sbQuery.Length)
{
sbQuery.Append("&");
}
if (string.IsNullOrWhiteSpace(queryKey) && !string.IsNullOrWhiteSpace(querys[queryKey]))
{
sbQuery.Append(querys[queryKey]);
}
if (!string.IsNullOrWhiteSpace(queryKey))
{
sbQuery.Append(queryKey);
if (!string.IsNullOrWhiteSpace(querys[queryKey]))
{
sbQuery.Append("=").Append(HttpUtility.UrlEncode(querys[queryKey], Encoding.UTF8));
}
}
}
if (0 < sbQuery.Length)
{
sbUrl.Append("?").Append(sbQuery);
}
}
return sbUrl.ToString();
}
public static string sign(string secret, string method, string path, Dictionary headers,
Dictionary querys, Dictionary bodys, List signHeaderPrefixList)
{
try
{
//return HmacSHA256(buildstringToSign(method, path, headers, querys, bodys, signHeaderPrefixList), secret);
/*---message里的内容---*/
//POST
//*/*
//application/json
//x-ca-key:23125513
//x-ca-nonce:12d28d90-a7c3-45cc-ae6a-0cc8d5e22118
//x-ca-timestamp:1544495633599
//artemis/api/resource/v1/org/advance/orgList
string message = buildstringToSign(method, path, headers, querys, bodys, signHeaderPrefixList);
return HmacSHA256(message, secret);
}
catch (Exception ex)
{
return ex.Message;
}
}
public static string buildstringToSign(string method, string path, Dictionary headers,
Dictionary querys, Dictionary bodys, List signHeaderPrefixList)
{
StringBuilder sb = new StringBuilder();
sb.Append(method.ToUpper()).Append("\n");
if (null != headers)
{
if (null != headers["Accept"])
{
sb.Append((string) headers["Accept"]);
sb.Append("\n");
}
if (headers.Keys.Contains("Content-MD5") && null != headers["Content-MD5"])
{
sb.Append((string) headers["Content-MD5"]);
sb.Append("\n");
}
if (null != headers["Content-Type"])
{
sb.Append((string) headers["Content-Type"]);
sb.Append("\n");
}
if (headers.Keys.Contains("Date") && null != headers["Date"])
{
sb.Append((string) headers["Date"]);
sb.Append("\n");
}
}
sb.Append(buildHeaders(headers, signHeaderPrefixList));
sb.Append(buildResource(path, querys, bodys));
return sb.ToString();
}
public static string buildHeaders(Dictionary headers, List signHeaderPrefixList)
{
StringBuilder sb = new StringBuilder();
if (null != signHeaderPrefixList)
{
signHeaderPrefixList.Remove("x-ca-signature");
signHeaderPrefixList.Remove("Accept");
signHeaderPrefixList.Remove("Content-MD5");
signHeaderPrefixList.Remove("Content-Type");
signHeaderPrefixList.Remove("Date");
signHeaderPrefixList.Sort();
}
if (null != headers)
{
Dictionary sortDictionary = new Dictionary();
sortDictionary = headers;
//按key值升序排序
var dicSort = from objDic in sortDictionary orderby objDic.Key ascending select objDic;
StringBuilder signHeadersStringBuilder = new StringBuilder();
foreach (KeyValuePair kvp in dicSort)
{
if (kvp.Key.Replace(" ", "").Contains("x-ca-"))
{
sb.Append(kvp.Key + ":");
if (!string.IsNullOrWhiteSpace(kvp.Value))
{
sb.Append(kvp.Value);
}
sb.Append("\n");
if (signHeadersStringBuilder.Length > 0)
{
signHeadersStringBuilder.Append(",");
}
signHeadersStringBuilder.Append(kvp.Key);
}
}
headers.Add("x-ca-signature-headers", signHeadersStringBuilder.ToString());
}
//x-ca-key:23125513
//x-ca-nonce:12d28d90-a7c3-45cc-ae6a-0cc8d5e22118
//x-ca-timestamp:1544495633599
return sb.ToString();
}
public static string buildResource(string path, Dictionary querys, Dictionary bodys)
{
StringBuilder sb = new StringBuilder();
if (!string.IsNullOrWhiteSpace(path))
{
sb.Append(path);
}
Dictionary sortDictionary = new Dictionary();
if (querys != null)
{
//按key值升序排序
var dicSort = from objDic in querys orderby objDic.Key ascending select objDic;
foreach (KeyValuePair kvp in dicSort)
{
if (!string.IsNullOrWhiteSpace(kvp.Key))
{
sortDictionary[kvp.Key] = kvp.Value;
}
}
}
if (bodys != null)
{
//按key值升序排序
var dicSort = from objDic in bodys orderby objDic.Key ascending select objDic;
foreach (KeyValuePair kvp in dicSort)
{
if (!string.IsNullOrWhiteSpace(kvp.Key))
{
sortDictionary[kvp.Key] = kvp.Value;
}
}
}
StringBuilder sbParam = new StringBuilder();
//按key值升序排序
var dicSortDictionary = from objDic in sortDictionary orderby objDic.Key ascending select objDic;
foreach (KeyValuePair kvp in dicSortDictionary)
{
if (!string.IsNullOrWhiteSpace(kvp.Key))
{
if (sbParam.Length > 0)
{
sbParam.Append("&");
}
sbParam.Append(kvp.Key);
if (!string.IsNullOrWhiteSpace(kvp.Value))
{
sbParam.Append("=").Append(kvp.Value);
}
}
}
if (0 < sbParam.Length)
{
sb.Append("?");
sb.Append(sbParam);
}
//artemis/api/resource/v1/org/advance/orgList
return sb.ToString();
}
public static string HmacSHA256(string message, string secret)
{
secret = secret ?? "";
var encoding = new System.Text.UTF8Encoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
public static Dictionary ConvertMapTimeStyle(Dictionary paramMap)
{
Dictionary timeMap = new Dictionary();
try
{
foreach (string key in paramMap.Keys)
{
object mapValueObj = paramMap[key];
Dictionary dic = mapValueObj as Dictionary;
if (dic != null)
{
ConvertMapTimeStyle(dic);
}
//时间格式参数转为ISO8601
DateTime mapDate;
if (DateTime.TryParse(paramMap[key].ToString(), out mapDate))
{
string ISO8601time = mapDate.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");
timeMap.Add(key, ISO8601time);
}
}
if (timeMap.Count > 0)
{
foreach (string key in timeMap.Keys)
{
paramMap[key] = timeMap[key];
}
}
return paramMap;
}
catch (Exception ex)
{
return paramMap;
}
}
public enum Method
{
GET,
POST_FORM,
POST_STRING,
POST_BYTES,
PUT_FORM,
PUT_STRING,
PUT_BYTES,
DELETE
}
public class Request
{
public Request()
{
}
public Request(Method method, string host, string path, string appKey, string appSecret, int timeout)
{
this.Method = method;
this.Host = host;
this.Path = path;
this.AppKey = appKey;
this.AppSecret = appSecret;
this.Timeout = timeout;
}
public Method Method { get; set; }
public string Host { get; set; }
public string Path { get; set; }
public string AppKey { get; set; }
public string AppSecret { get; set; }
public int Timeout { get; set; }
public Dictionary Headers { get; set; }
public Dictionary Querys { get; set; }
public Dictionary Bodys { get; set; }
public string StringBody { get; set; }
public byte[] BytesBody { get; set; }
public List SignHeaderPrefixList { get; set; }
}
}