.NET调用腾讯云API实例

最近项目有用到腾讯云的身份识别接口,话不多说,直接上代码:

  1         private void IDCardVerification(HttpContext context)
  2         {
  3             
  4             string imgStr = context.Request["ImageBase64"];
  5             if (!string.IsNullOrEmpty(imgStr))
  6             {
  7                 try
  8                 {
  9                     //请求地址
 10                     string settingUrl = ConfigurationManager.AppSettings.Get("IDCardVerifUrl");
 11                     //应用ID
 12                     string secretId = ConfigurationManager.AppSettings.Get("TcCloudSecretId");
 13                     //应用key
 14                     string secretKey = ConfigurationManager.AppSettings.Get("TcCloudSecretKey");
 15                     //时间戳
 16                     string timesTamp = GetTimeStamp();
 17                     //Nonce
 18                     var nonce = new Random().Next(10000, 99999);
 19                     //拼接参数
 20                     string paramsStr = string.Format(@"Action=IDCardOCR&CardSide=FRONT&ImageBase64={0}&Nonce={1}&Region=ap-guangzhou&SecretId={2}&SignatureMethod=HmacSHA1&Timestamp={3}&Version=2018-11-19",
 21                         imgStr, nonce, secretId, timesTamp);
 22                     //生成签名参数
 23                     string requestText = "POST" + settingUrl.Replace("https://", "") + "?" + paramsStr;
 24                     //获得请求签名
 25                     string signText = GetHmacSha1Sign(secretKey, requestText);
 26                     //这里一定要进行URL编码,不然调用API会报错
 27                     signText = HttpUtility.UrlEncode(signText, Encoding.UTF8);
 28                     imgStr = HttpUtility.UrlEncode(imgStr, Encoding.UTF8);
 29                     paramsStr = string.Format(@"Action=IDCardOCR&CardSide=FRONT&ImageBase64={0}&Nonce={1}&Region=ap-guangzhou&SecretId={2}&Signature={3}&SignatureMethod=HmacSHA1&Timestamp={4}&Version=2018-11-19",
 30                         imgStr, nonce, secretId, signText, timesTamp);
 31                     //请求腾讯API,返回身份证信息
 32                     string resultStr = Globals.SendRequest(settingUrl, paramsStr);
 33                     var idCard = new JavaScriptSerializer().Deserialize<IDCardVerif>(resultStr);
 34                     var iDCardInfo = idCard.Response;
 35                     if (iDCardInfo.Error != null)
 36                     {
 37                         context.Response.Write("{\"Status\":\"fail\",\"errorMsg\":\"身份证识别出错: " + iDCardInfo.Error.Message + " \"}");
 38                     }
 39                     else
 40                     {
 41                         var result = new { Status = "success", data = new { iDCardInfo.name, iDCardInfo.Sex, iDCardInfo.Nation, iDCardInfo.IdNum, iDCardInfo.Address, iDCardInfo.Birth } };
 42                         context.Response.Write(new JavaScriptSerializer().Serialize(result));
 43                     }
 44                 }
 45                 catch (Exception ex)
 46                 {
 47                     context.Response.Write("{\"Status\":\"fail\",\"errorMsg\":\"请求接口出错 \"}");
 48                 }
 49             }
 50             else
 51             {
 52                 context.Response.Write("{\"Status\":\"fail\",\"errorMsg\":\"请选择上传的图片!\"}");
 53             }
 54 
 55 
 56         }
 57 
 58 
 59         /// <summary> 
 60         /// 获取时间戳 
 61         /// </summary> 
 62         /// <returns></returns> 
 63         public static string GetTimeStamp()
 64         {
 65             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
 66             return Convert.ToInt64(ts.TotalSeconds).ToString();
 67         }
 68 
 69         /// <summary>
 70         /// HMAC-SHA1加密返回签名
 71         /// </summary>
 72         /// <param name="secret">密钥</param>
 73         /// <param name="strOrgData">源文</param>
 74         /// <returns></returns>
 75         public static string GetHmacSha1Sign(string secret, string strOrgData)
 76         {
 77             var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret));
 78             var dataBuffer = Encoding.UTF8.GetBytes(strOrgData);
 79             var hashBytes = hmacsha1.ComputeHash(dataBuffer);
 80             return Convert.ToBase64String(hashBytes);
 81         }
 82 
 83        public static string SendRequest(string url, string completeUrl)
 84         {
 85             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
 86             request.Method = "POST";
 87             request.ContentType = "application/x-www-form-urlencoded";
 88             request.ProtocolVersion = HttpVersion.Version10;
 89             request.Host = url.Replace("https://", "").Replace("/", "");
 90             byte[] data = Encoding.UTF8.GetBytes(completeUrl);
 91             request.ContentLength = data.Length;
 92             Stream newStream = request.GetRequestStream();
 93             newStream.Write(data, 0, data.Length);
 94             newStream.Close();
 95             HttpWebResponse response = null;
 96             string content;
 97             try
 98             {
 99                 response = (HttpWebResponse)request.GetResponse();
100                 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
101                 content = reader.ReadToEnd();
102             }
103             catch (WebException e)
104             {
105                 response = (HttpWebResponse)e.Response;
106                 using (Stream errData = response.GetResponseStream())
107                 {
108                     using (StreamReader reader = new StreamReader(errData))
109                     {
110                         content = reader.ReadToEnd();
111                     }
112                 }
113             }
114             return content;
115         }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Hmeshop.Entities
{
    public class IDCardVerif
    {
        public IDCardVerifInfo Response { get; set; }

    }

    public class IDCardVerifInfo
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public string Sex { get; set; }

        /// <summary>
        /// 民族
        /// </summary>
        public string Nation { get; set; }

        /// <summary>
        /// 生日
        /// </summary>
        public string Birth { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 身份证号
        /// </summary>
        public string IdNum { get; set; }

        /// <summary>
        /// 发证机关
        /// </summary>
        public string Authority { get; set; }

        /// <summary>
        /// 证件有效期
        /// </summary>
        public string ValidDate { get; set; }

        /// <summary>
        /// 扩展信息
        /// </summary>
        public string AdvancedInfo { get; set; }

        /// <summary>
        /// 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        /// </summary>
        public string RequestId { get; set; }

        /// <summary>
        /// 错误信息,有则返回,没有则为空
        /// </summary>
        public ErrorInfo Error { get; set; }

    }

    public class ErrorInfo {

        public string Code { get; set; }

        public string Message { get; set; }

    }




}

 

开始的时候,使用了HTTP的POST这种请求方式进行调用,但后面发现这种请求方式有Bug,一旦用户上传的图片尺寸太大(跟图片大小没关系,主要是尺寸),请求腾讯的API就会返回下面这个错误(PS:因为我这边使用的是OCR身份证识别API,如果不涉及图片文件的话,可以使用我上面的调用方式):

 

 .NET调用腾讯云API实例

根据图上的错误信息可知,需要用到TC3-HMAC-SHA256这个签名算法,So,没办法,我们只能用腾讯的SDK来调用了,SDK直接在VS的Nuget里下载就好了,在GitHub下载源码进行编译引用也行

下面贴腾讯官方SDK调用代码:

 1        private void IDCardVerificationBySDK(HttpContext context)
 2         {           
 3             string imgStr = context.Request["ImageBase64"];          
 4             try
 5             {
 6                 if (!string.IsNullOrEmpty(imgStr))
 7                 {
 8                     string res = string.Empty;
 9 
10                     Action<string> action = t =>
11                     {
12                         res = GetOCRMsg(imgStr);
13                     };
14                     IAsyncResult asyncResult = action.BeginInvoke("调用腾讯云身份证识别", null, null);
15                     asyncResult.AsyncWaitHandle.WaitOne();
16                     if (res.Contains("message"))
17                     {
18                         context.Response.Write("{\"Status\":\"fail\",\"errorMsg\":\"" + res.Split(new string[] { "message:" }, StringSplitOptions.None)[1] + "\"}");
19                     }
20                     else
21                     {
22                         IDCardOCRResponse resp = JsonConvert.DeserializeObject<IDCardOCRResponse>(res);
23                         var result = new { Status = "success", data = resp };
24                         context.Response.Write(JsonConvert.SerializeObject(result));
25                     }
26                 }
27                 else
28                 {
29                     context.Response.Write("{\"Status\":\"fail\",\"errorMsg\":\"请选择上传的图片!\"}");
30                 }
31             }
32             catch(Exception ex)
33             {
34                 Globals.Debuglog("调用接口出错:" + ex.StackTrace, "Tentent_IDCardVerif.txt");
35             }
36             
37         }
38 
39 
40         private string GetOCRMsg(string imgStr)
41         {
42             try
43             {
44                 Credential cred = new Credential
45                 {
46                     SecretId = ConfigurationManager.AppSettings.Get("TcCloudSecretId"),
47                     SecretKey = ConfigurationManager.AppSettings.Get("TcCloudSecretKey")
48                 };
49 
50                 ClientProfile clientProfile = new ClientProfile
51                 {
52                     SignMethod = ClientProfile.SIGN_TC3SHA256
53                 };
54                 HttpProfile httpProfile = new HttpProfile();
55                 httpProfile.Endpoint = ("ocr.tencentcloudapi.com");
56                 httpProfile.ReqMethod = "POST";
57                 httpProfile.Timeout = 10; // 请求连接超时时间,单位为秒(默认60秒)
58                 clientProfile.HttpProfile = httpProfile;
59                 OcrClient client = new OcrClient(cred, "ap-guangzhou", clientProfile);
60                 IDCardOCRRequest req = new IDCardOCRRequest();
61                 string strParams = "{\"ImageBase64\":\""+ imgStr + "\",\"CardSide\":\"FRONT\",\"ImageUrl\":\"\",\"Config\":\"\"}";
62                 Globals.Debuglog("strParams: " + strParams, "Tentent_IDCardVerif.txt");
63                 req = JsonConvert.DeserializeObject<IDCardOCRRequest>(strParams);
64                 IDCardOCRResponse resp = client.IDCardOCR(req).
65                     ConfigureAwait(false).GetAwaiter().GetResult();
66                 return AbstractModel.ToJsonString(resp);
67             }
68             catch (Exception e)
69             {
70                 Globals.Debuglog("请求接口出错:" + e.StackTrace, "Tentent_IDCardVerif.txt");
71                 return e.Message.ToString();
72             }
73         }
74 

 

这里要注意的是,一定要使用异步请求的方式进行调用! 不然直接调用的话,执行到:

ConfigureAwait(false).GetAwaiter().GetResult();

这一步会没有任何响应,程序陷入假死状态,博主就是在这里踩了坑,尝试了多次才发现这个问题,真是坑爹啊- -!

 

好了,就先说到这里了,这是本人在博客园的处女blog,希望给各位有需要的人一点帮助哈~

 

.NET调用腾讯云API实例

上一篇:不能访问windows installer服务


下一篇:ABP WebApi的请求类型