.NET調用騰訊雲API實例

来源:https://www.cnblogs.com/CristianoRonaldo/archive/2019/08/05/11301859.html
-Advertisement-
Play Games

最近項目有用到騰訊雲的身份識別介面,話不多說,直接上代碼: 開始的時候,使用了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,如果不涉及圖片文件的話,可以使用我上面的調用方式):

 

 

根據圖上的錯誤信息可知,需要用到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,希望給各位有需要的人一點幫助哈~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • SmartSql = MyBatis + Cache(Memory | Redis) + R/W Splitting +Dynamic Repository + Diagnostics ...... ...
  • 安裝相關依賴:NPinyin Microsoft.International.Converters.PinYinConverter 直接從vs裡面的nuget管理器搜索下載即可。 ...
  • 上接(abp(net core)+easyui+efcore實現倉儲管理系統——使用 WEBAPI實現CURD (十一)),在這一篇文章中我們創建服務介面與服務實現類,並創建控制器類。 ...
  • 公司的網站需要有些新聞,每次的新聞格式都是一樣的,而不想每次都查詢操作,所以想把這些新聞的頁面保存成靜態的html,之後搜索了下就找到了這個模板引擎,當然其他的模板引擎可以的,例如:Razor,自己寫的手動替換等。NVelocity是Apache Jakarta Velocity中的一個優秀項目,有 ...
  • 資料庫連接釋放問題 “超時時間已到。超時時間已到,但是尚未從池中獲取連接。出現這種情況可能是因為所有池連接均在使用,並且達到了最大池大小。”一看就是資料庫連接池滿了,應該是打開後沒有釋放的原因,但是我的Connection對象都使用using及時釋放了,怎麼會出現這種情況呢?花了很長時間終於到了原因 ...
  • 第一分鐘:委托 有些教材,博客說到委托都會提到事件,雖然事件是委托的一個實例,但是為了理解起來更簡單,今天只談委托不談事件。先上一段代碼: 下邊的代碼,完成了一個委托應用的演示。一個委托分三個步驟: step01:首先用delegate定義一個委托 。 step02:聲明一個方法來對應委托。 ste ...
  • 我們已經講了人臉識別(入門+進階)、圖片識別(入門)。下麵是鏈接: C# 10分鐘完成百度人臉識別——入門篇 C# 30分鐘完成百度人臉識別——進階篇(文末附源碼) C# 10分鐘完成百度圖片提取文字(文字識別)——入門篇 今天我們來盤一盤語音識別與合成。 PS:僅供瞭解參考,如需進一步瞭解請繼續研 ...
  • C# Hello World實例 一個C#程式註意包括以下部分: 命名空間聲明(Namespace declaration) 一個class Class方法 Class屬性 一個Main方法 語句(Statements) & 表達式(Expressions) 註釋 讓我們看看一個可以列印出 "Hel ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...