.NET Core/C# 对接成都智慧工地《建筑垃圾运渣车辆视频监控系统》
1.首先从运渣车识别对接QQ群下载并阅读成都市智慧工地建筑垃圾运渣车辆在线视频监控系统接口及功能要求说明书
文档里面只有两个接口,一个获取授权设备列表。另一个是上传识别数据。下面是对接过程中遇到的问题以及解决方案。
对接完成后,还需要从现场设备获取数据上传至建委,并且识别错误率不超过10%,就算拿到资质了。
2.从群里负责人获取测试账号(appKey,appSecret),并把自己的设备序列号发给负责人将其加入测试库。接下来就可以开始写代码对接了。
3.第一个接口通过 GetAuth 获取设备与 Key 值(会在第二个接口中用到),下面是通过 RestRequest 方式发起的 POST 请求代码:
/// <summary>获取设备密钥</summary>
public async Task<object> GetVehicleIdentificationDeviceList(VehicleIdentificationGetAccessTokenInput input)
{
input.SetPrivateKeyAndSign("9708B6AE9100DDE83B2EB8F6487C7317");//appKey
var request = new RestRequest($"/Service/DistinguishWebSvr.assx/GetAuth", Method.POST, DataFormat.None);
request.AddParameter("appKey", input.Key);
request.AddParameter("deviceNumber", input.SerialNumber);
request.AddParameter("sign", input.Sign);
var client = new RestClient("Url");
var response = client.Execute(request);
return response.Content;
}
上面代码中一般会遇到第一个问题“如何生成HMACMD5”,下面是这个问题在C#里面的答案。
/// <summary>
/// 对传递参数进行加签使用 HMACMD5 方式
/// </summary>
/// <param name="input">加签值</param>
/// <param name="privateKey">私钥 密钥</param>
/// <returns></returns>
public void ToMd5(string input, string privateKey)
{
var hmacmdb = new HMACMD5(Encoding.UTF8.GetBytes(privateKey));
var bytes = hmacmdb.ComputeHash(Encoding.UTF8.GetBytes(input));
var md5 = BitConverter.ToString(bytes).Replace("-", "");
Sign = md5;
}
第一个接口还可以通过1024程序员开发工具箱网站直接获取 sign 然后通过 Postman 或其他方式验证。到这里第一个接口就对通了,并能成功拿到如文档中描述的返回数据。
4.第二个接口通过 UploadCarData 方法上传识别数据。
/// <summary>上传车辆识别数据</summary>
public async Task<object> UploadCarDataVehicleIdentification(VehicleIdentificationUploadCarDataInput input)
{
var bytes = File.ReadAllBytes(@"图片路径");
input.Image = bytes;
input.SetPrivateKeyAndSign("27112411");//这是第一个接口种的 Key
var request = new RestRequest($"/Service/DistinguishWebSvr.assx/UploadCarData", Method.POST, DataFormat.None);
request.AddParameter("carInfo", input.carInfo);
request.AddFileBytes("image", bytes, "20191114173358.jpg");//文件名并包含后缀
request.AddParameter("sign", input.Sign);
var client = new RestClient("Url");
var response = client.Execute(request);
return response.Content;
}
这个接口可能会遇到下面的问题:
- 如何获取文件 byte[] 值;(本地使用 File.ReadAllBytes 方法,也可以通过获取 base64 然后再通过 Convert.FromBase64String("base64字符串"))
- 如何在 RestClient 中传递 byte[] 值;(使用 AddFileBytes 方法,注意第三个参数文件名需要包含后缀)
- 如何合并两个 byte[] 值;(使用 CopyTo 方法)
- 加签时是用 appKey 还是 appSecret;(都不是,使用 GetAuth 接口返回的设备对应的 Key)
- 各种验签不通过;(可能是 carInfo 的数据类型导致服务端验签失败,将 carInfo 属性改为 string 类型)
5.最后是两个方法的输入参数以及加签的方法合并到下面类中
using Newtonsoft.Json;
using System;
using System.Security.Cryptography;
using System.Text;
namespace ThirdParty.Device.InputModels
{
/// <summary>
/// 建筑垃圾运渣车辆获取 设备与密钥
/// </summary>
public class VehicleIdentificationGetAccessTokenInput : VehicleIdentificationAccessTokenInput
{
/// <summary>公钥</summary>
[JsonProperty("appKey")] public string Key { get; set; }
/// <summary>设备序列号</summary>
[JsonProperty("deviceNumber")] public string SerialNumber { get; set; }
/// <summary>
/// 设置私钥并加签
/// </summary>
/// <param name="privateKey"></param>
public void SetPrivateKeyAndSign(string privateKey)
{
ToMd5(Key + SerialNumber, privateKey);
}
}
/// <summary>
/// 上传车辆识别数据
/// </summary>
public class VehicleIdentificationUploadCarDataInput : VehicleIdentificationAccessTokenInput
{
/// <summary>车辆识别信息</summary>
[JsonProperty("carInfo")]
public string carInfo { get; set; }
/// <summary>车辆识别图片(包含车牌,见图 1)</summary>
[JsonProperty("image")]
public byte[] Image { get; set; }
/// <summary>车辆冲洗图片</summary>
[JsonProperty("cleanImage")]
public byte[] CleanImage { get; set; }
/// <summary>车辆识别图片 1(预留)</summary>
[JsonProperty("image1")]
public byte[] Image1 { get; set; }
/// <summary>车辆识别图片 2(预留)</summary>
[JsonProperty("image2")]
public byte[] Image2 { get; set; }
/// <summary>车辆识别图片 3(预留)</summary>
[JsonProperty("image3")]
public byte[] Image3 { get; set; }
/// <summary>
/// 设置私钥并加签
/// </summary>
/// <param name="key"></param>
public void SetPrivateKeyAndSign(string key)
{
var jsonBytes = Encoding.UTF8.GetBytes(carInfo);
var len = jsonBytes.Length + Image.Length;
len += CleanImage?.Length ?? 0;
len += Image1?.Length ?? 0;
len += Image2?.Length ?? 0;
len += Image3?.Length ?? 0;
var totalBytes = new byte[len];
jsonBytes.CopyTo(totalBytes, 0);
Image.CopyTo(totalBytes, jsonBytes.Length);
Image1?.CopyTo(totalBytes, jsonBytes.Length + Image1.Length);
var hmacmdb = new HMACMD5(Encoding.UTF8.GetBytes(key));
var bytes = hmacmdb.ComputeHash(totalBytes);
Sign = BitConverter.ToString(bytes).Replace("-", "");
}
public byte[] GetBytes(string input)
{
return Convert.FromBase64String(input);
}
}
public class CarEntryExitInfo
{
/// <summary>设备序列号</summary>
public string DeviceNumber { get; set; }
/// <summary>抓拍时间</summary>
public string SnapDate { get; set; }
/// <summary>车辆类型:(0:轿车,1:运渣车,2:罐车)</summary>
public string CarModel { get; set; }
/// <summary>车牌号</summary>
public string CarNumber { get; set; }
/// <summary>出入类型(1:进场;2:出场)</summary>
public string Type { get; set; }
}
/// <summary>
/// 加签
/// </summary>
public class VehicleIdentificationAccessTokenInput
{
/// <summary>数字签名</summary>
[JsonProperty("sign")] public string Sign { get; set; }
/// <summary>
/// 对传递参数进行加签使用 HMACMD5 方式
/// </summary>
/// <param name="input"></param>
/// <param name="privateKey">私钥 密钥</param>
/// <returns></returns>
public void ToMd5(string input, string privateKey)
{
var hmacmdb = new HMACMD5(Encoding.UTF8.GetBytes(privateKey));
var bytes = hmacmdb.ComputeHash(Encoding.UTF8.GetBytes(input));
var md5 = BitConverter.ToString(bytes).Replace("-", "");
Sign = md5;
}
}
}
后面对接的朋友,如果发现有新的对接情况,请反馈我们会及时更新。