我正在尝试使用
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中如果我在图片中发送这个请求。
它给了我一个错误,因为我也没有设置我的 json 正文数据。
2°请求
然后,我尝试使用多部分发送它。
它有文件和 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;
}
我放弃了这种尝试。我现在用faceURL来做。
{
"faceLibType": "blackFD",
"FDID": "1",
"FPID": "9",
"faceURL": "https://192.168.0.128:3000/avatar/11aa3bc9b410187df1907ad4092eedb3.jpg"
}
我认为可以存储的图像的最大大小是 200kb,如相机网络管理中的通知。 所以不能添加比它更多的图像。 管理页面:http://192.168.1.230/#/home/peopleManage 注意:“图片格式应为JPEG,大小应小于200K。” 或者你可以查看这个问题:
如何创建包含json和二进制图像数据的multipart/form-data,然后将其序列化并传递给IntPtr?
谢谢
我用以下代码完成了它(尝试遵循 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设置