如何在POST请求海康威视ISAPI中发送多部分数据

问题描述 投票:0回答:3

我正在尝试使用

DS-K1T671M Facial Recognition Device from Hikvision
将图片发送到
Hikvision ISAPI

文档说我需要打电话

POST /ISAPI/Intelligent/FDLib/FaceDataRecord?format=json

body:

{
  "faceLibType": "blackFD",
  "FDID": "1",
  "FPID": "1"
}

它说我需要发送这个正文+一张二进制图片。因此我需要发送多部分数据(图片+JSON内容)。

1°请求

因此,在Postman中如果我在图片中发送这个请求。

enter image description here

它给了我一个错误,因为我也没有设置我的 json 正文数据。

2°请求

然后,我尝试使用多部分发送它。

enter image description here

它有文件和 JSON,但仍然不起作用。

文档中的示例

我将发布文档中的请求

Example
Add Face Record When Binary Picture is Uploaded in Form Format
1) POST /ISAPI/Intelligent/FDLib/FaceDataRecord?format=json
2) Accept: text/html, application/xhtml+xml,
3) Accept-Language: us-EN
4) Content-Type: multipart/form-data;boundary=-------------------7e
5) User-Agent: Mozilla/5.0 (cŽmƉĂtibůĞ͖ MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
6) Accept-Encoding: gzip, deflate
7) Host: 10.10.36.29:8080
8) Content-Length: 9907
9) Connection: Keep-Alive
10) Cache-Control: no-cache
11)
12) -----------------------------7e13971310878
13) Content-Disposition: form-data; name="FaceDataRecord";
14) Content-Type: application/json
15) Content-Length: 9907
16)
17) {
a) "faceLibType": "blackFD",
b) "FDID": "1223344455566788",
c) "FPID": "11111aa"
18) }
19) -----------------------------7e13971310878
20) Content-Disposition: form-data; name="FaceImage";
21) Content-Type: image/jpeg
22) Content-Length: 9907
23)
24) ......JFIF.....`.`.....C........... .
25) ..
26) ................. $.' ",#..(7),01444.'9=82<.342...C. ....
27) -----------------------------7e13971310878--

他们有一个 C# 工作示例

{
  szUrl = "/ISAPI/Intelligent/FDLib/FaceDataRecord?format=json";

  if (!szUrl.Substring(0, 4).Equals("http"))
  {
    szUrl = "http://" + AddDevice.struDeviceInfo.strDeviceIP + ":" + AddDevice.struDeviceInfo.strHttpPort + szUrl;
  }
  HttpClient clHttpClient = new HttpClient();
  szResponse = string.Empty;
  szRequest = "{\"faceLibType\":\"" + comboBoxFaceType.SelectedItem.ToString() +
    "\",\"FDID\":\""+textBoxFDID.Text+
    "\",\"FPID\":\""+textBoxEmployeeNo.Text+"\"}";
  string filePath = textBoxFilePath.Text;
  szResponse = clHttpClient.HttpPostData(AddDevice.struDeviceInfo.strUsername, AddDevice.struDeviceInfo.strPassword, szUrl, filePath, szRequest);
  ResponseStatus res = JsonConvert.DeserializeObject<ResponseStatus>(szResponse);
    if (res!=null && res.statusCode.Equals("1"))
      {
        MessageBox.Show("Set Picture Succ!");
        return;
      }
      MessageBox.Show("Set Picture Failed!");
}

public string HttpPostData(string strUserName, string strPassword, string url,
            string filePath, string request)
        {
            string responseContent = string.Empty;
            var memStream = new MemoryStream();
            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            // 边界符  
            var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
            // 边界符  
            var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
            var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            // 最后的结束符  
            var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");

            // 设置属性  
            webRequest.Credentials = GetCredentialCache(url, strUserName, strPassword);
            webRequest.Timeout = m_iHttpTimeOut;
            webRequest.Method = "POST";
            webRequest.Accept = "text/html, application/xhtml+xml,";
            webRequest.Headers.Add("Accept-Language", "zh-CN");
            webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
            webRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
            webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
            webRequest.Headers.Add("Cache-Control", "no-cache");
            //写入JSON报文
            string header =
                "Content-Disposition: form-data; name=\"FaceDataRecord\";\r\n" +
                "Content-Type: application/json\r\n" +
                "Content-Length: "+request.Length+"\r\n\r\n";
            var headerBytes = Encoding.UTF8.GetBytes(header);
            var requestBytes = Encoding.UTF8.GetBytes(request);
            memStream.Write(beginBoundary, 0, beginBoundary.Length);
            memStream.Write(headerBytes,0,headerBytes.Length);
            memStream.Write(requestBytes,0,requestBytes.Length);

            var buffer = new byte[fileStream.Length];

            fileStream.Read(buffer, 0, buffer.Length);
            fileStream.Close();

            // 写入文件  
            header = "\r\n--"+boundary+"\r\n"+
                "Content-Disposition: form-data; name=\"FaceImage\";\r\n" +
                 "Content-Type: image/jpeg\r\n"+
                 "Content-Length: " +buffer.Length+"\r\n\r\n";
            headerBytes = Encoding.UTF8.GetBytes(header);

            memStream.Write(headerBytes, 0, headerBytes.Length);
            memStream.Write(buffer, 0, buffer.Length);
            var contentLine = Encoding.ASCII.GetBytes("\r\n");
            memStream.Write(contentLine, 0, contentLine.Length);

            // 写入最后的结束边界符  
            memStream.Write(endBoundary, 0, endBoundary.Length);

            webRequest.ContentLength = memStream.Length;

            var requestStream = webRequest.GetRequestStream();

            memStream.Position = 0;
            var tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

            requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            requestStream.Close();

            try
            {
                var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();

                using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
                                                                Encoding.GetEncoding("utf-8")))
                {
                    responseContent = httpStreamReader.ReadToEnd();
                }
                httpWebResponse.Close();
            }
            catch(WebException ex)
            {
                MessageBox.Show(ex.ToString());
            }
            fileStream.Close();
            
            webRequest.Abort();

            return responseContent;
        }
api multipart hikvision
3个回答
3
投票

我放弃了这种尝试。我现在用faceURL来做。

{
  "faceLibType": "blackFD",
  "FDID": "1",
  "FPID": "9",
  "faceURL": "https://192.168.0.128:3000/avatar/11aa3bc9b410187df1907ad4092eedb3.jpg"
}

1
投票

我认为可以存储的图像的最大大小是 200kb,如相机网络管理中的通知。 所以不能添加比它更多的图像。 管理页面:http://192.168.1.230/#/home/peopleManage 注意:“图片格式应为JPEG,大小应小于200K。” 或者你可以查看这个问题:

如何创建包含json和二进制图像数据的multipart/form-data,然后将其序列化并传递给IntPtr?

谢谢


0
投票

我用以下代码完成了它(尝试遵循 HttpPostData 中的编码方式):

var handler = new HttpClientHandler { PreAuthenticate = true };
handler.Credentials = new NetworkCredential(device.Username, device.Password);

using (var client = new HttpClient(handler))
{
    // Create a custom boundary
    var boundary = $"---------------{DateTime.Now.Ticks:x}";

    // Manually construct the multipart/form-data content
    using var content = new MultipartFormDataContent(boundary);
    content.Headers.Remove("Content-Type");
    content.Headers.TryAddWithoutValidation("Content-Type", $"multipart/form-data; boundary={boundary}");

    // Add JSON data
    var faceDataRecord = new { faceLibType = "blackFD", FDID = "1", FPID = staffId };
    var jsonContent = new StringContent(JsonSerializer.Serialize(faceDataRecord), System.Text.Encoding.UTF8, "application/json");
    content.Add(jsonContent, "FaceDataRecord");

    // Add image file
    byte[] imageBytes = await File.ReadAllBytesAsync(filePath);
    var imageContent = new ByteArrayContent(imageBytes);
    imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
    content.Add(imageContent, "FaceImage", Path.GetFileName(filePath));

    var response = await client.PutAsync(url, content);

    return await response.Content.ReadAsStringAsync();
}

最关键的部分是添加边界并进行手动Content-Type设置

© www.soinside.com 2019 - 2024. All rights reserved.