欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET调用腾讯云API实例

程序员文章站 2022-06-20 23:11:19
最近项目有用到腾讯云的身份识别接口,话不多说,直接上代码: 开始的时候,使用了HTTP的POST这种请求方式进行调用,但后面发现这种请求方式有Bug,一旦用户上传的图片尺寸太大(跟图片大小没关系,主要是尺寸),请求腾讯的API就会返回下面这个错误(PS:因为我这边使用的是OCR身份证识别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();

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