HttpClientService.cs:
/// <summary> /// HTTP請求方法 /// 兼容微信支付V3版本api請求 /// </summary> public class HttpClientService { private static HttpClientService _instance; private static readonly object _lock = new object(); private static HttpClient _client; public HttpClientService() { } public static HttpClientService GetInstance() { if (_instance == null) { lock (_lock) { if (_instance == null) { _instance = new HttpClientService(); } if (_client == null) { _client = new HttpClient(); } } } return _instance; } /// <summary> /// 參數(shù)對象轉(zhuǎn)換為uri網(wǎng)址參數(shù)形式 (主要用于GET的url生成) /// </summary> /// <param name="obj"></param> /// <param name="url"></param> /// <returns></returns> public static string GetUriParam(object obj, string url = "") { PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); StringBuilder sb = new StringBuilder(); sb.Append(url); sb.Append("?"); foreach (var p in properties) { var v = p.GetValue(obj, null); if (v == null) continue; sb.Append(p.Name); sb.Append("="); sb.Append(Uri.EscapeDataString(v.ToString()));//將字符串轉(zhuǎn)換為它的轉(zhuǎn)義表示形式,HttpUtility.UrlEncode是小寫 sb.Append("&"); } sb.Remove(sb.Length - 1, 1); return sb.ToString(); } /// <summary> /// Get方法 /// </summary> /// <param name="url">請求的地址</param> /// <param name="authorization">Authorization標(biāo)頭 scheme:認(rèn)證類型 parameter:簽名信息 /// 如:Bearer your_access_token、API-Key your_api_key,微信支付V3的 WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\" /// { scheme = "Bearer", parameter="your_access_token" }、 /// { scheme = "API-Key", parameter="your_api_key" }、 /// { scheme = "WECHATPAY2-SHA256-RSA2048", parameter="mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"" } /// </param> /// <param name="accept">Accept代表發(fā)送端(客戶端)希望接受的數(shù)據(jù)類型。 比如:Accept:text/xml; 代表客戶端希望接受的數(shù)據(jù)類型是xml類型。放在請求頭中。</param> /// <param name="encoding">編碼方式 默認(rèn)為UTF8</param> /// <param name="timeOut">默認(rèn)值是 100 秒,單位為秒</param> /// <returns></returns> public static string HttpGet(string url, HttpAuthorization authorization = null, string userAgent = "", string accept = "application/json", Encoding encoding = null, int timeOut = 100) { string result = ""; HttpResultModel model = null; //編碼方式 if (encoding == null) { encoding = Encoding.UTF8; } try { if (_client.BaseAddress is null) { _client.BaseAddress = new Uri(url); } //超時設(shè)置 _client.Timeout = TimeSpan.FromSeconds(timeOut); //Accept代表發(fā)送端(客戶端)希望接受的數(shù)據(jù)類型 if (!string.IsNullOrWhiteSpace(accept)) { _client.DefaultRequestHeaders.Accept.Clear(); _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); } //HTTP頭User-Agent if (!string.IsNullOrWhiteSpace(userAgent)) { string USER_AGENT = string.Format("{2} ({0}) .net/{1}", Environment.OSVersion, Environment.Version, userAgent); _client.DefaultRequestHeaders.Add("user-agent", USER_AGENT); } //Authorization Bearer your_access_token、API-Key your_api_key if (authorization != null) { _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authorization.scheme, authorization.parameter); } //能解讀https類型 指定 ServicePoint 安全協(xié)議 if (url.StartsWith("https")) { ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; } using (HttpResponseMessage response = _client.GetAsync(url).Result) { response.EnsureSuccessStatusCode(); string body = response.Content.ReadAsStringAsync().Result; string serial = ((string[])response.Headers.GetValues("Wechatpay-Serial"))[0].ToString(); string signature = ((string[])response.Headers.GetValues("Wechatpay-Signature"))[0].ToString(); string timestamp = ((string[])response.Headers.GetValues("Wechatpay-Timestamp"))[0].ToString(); string nonce = ((string[])response.Headers.GetValues("Wechatpay-Nonce"))[0].ToString(); //構(gòu)造驗簽名串 string signSource = timestamp + "\n" + nonce + "\n" + body + "\n"; model = new HttpResultModel() { code = 0, message = "成功", data = body, serial = serial, //微信支付V3 驗證簽名時 需要 signature = signature, //微信支付V3 驗證簽名時 需要 signSource = signSource //微信支付V3 驗證簽名時 需要 }; } } catch (Exception ex) { var actualException = ex.InnerException; if (actualException != null) { if (actualException is SocketException) { model = new HttpResultModel() { code = -1, message = "網(wǎng)絡(luò)中斷," + ex.Message }; } else if (actualException is TimeoutException) { model = new HttpResultModel() { code = -1, message = "連時超時," + ex.Message }; } else if (actualException is WebException webEx) { switch (webEx.Status) { case WebExceptionStatus.NameResolutionFailure: { // DNS 域名解析失敗的處理邏輯 model = new HttpResultModel() { code = -1, message = "無法解析主機名," + ex.Message }; break; } case WebExceptionStatus.ConnectFailure: { //The remote service point could not be contacted at the transport level. model = new HttpResultModel() { code = -1, message = "連接失敗," + ex.Message }; break; } case WebExceptionStatus.RequestCanceled: { //The request was canceled, the System.Net.WebRequest.Abort method was called, or an unclassifiable error occurred. This is the default value for System.Net.WebException.Status. model = new HttpResultModel() { code = -1, message = "請求被取消," + ex.Message }; break; } case WebExceptionStatus.ConnectionClosed: { //The connection was prematurely closed. model = new HttpResultModel() { code = -1, message = "連接關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.ReceiveFailure: { //A complete response was not received from the remote server. model = new HttpResultModel() { code = -1, message = "未收到遠(yuǎn)程服務(wù)器的響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.SendFailure: { //A complete request could not be sent to the remote server. model = new HttpResultModel() { code = -1, message = "無法向遠(yuǎn)程服務(wù)器發(fā)送請求," + ex.Message }; break; } case WebExceptionStatus.PipelineFailure: { //The request was a pipelined request and the connection was closed before the response was received. model = new HttpResultModel() { code = -1, message = "收到響應(yīng)之前關(guān)閉了連接," + ex.Message }; break; } case WebExceptionStatus.ProtocolError: { //The response received from the server was complete but indicated a protocol-level or example, an HTTP protocol error such as 401 Access Denied would use this status. model = new HttpResultModel() { code = -1, message = "HTTP協(xié)議錯誤," + ex.Message }; break; } case WebExceptionStatus.TrustFailure: { //A server certificate could not be validated. model = new HttpResultModel() { code = -1, message = "無法驗證服務(wù)器證書," + ex.Message }; break; } case WebExceptionStatus.SecureChannelFailure: { //An error occurred while establishing a connection using SSL. model = new HttpResultModel() { code = -1, message = "使用SSL建立連接時出錯," + ex.Message }; break; } case WebExceptionStatus.ServerProtocolViolation: { //The server response was not a valid HTTP response. model = new HttpResultModel() { code = -1, message = "服務(wù)器響應(yīng)不是有效的HTTP響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.KeepAliveFailure: { //The connection for a request that specifies the Keep-alive header was closed unexpectedly. model = new HttpResultModel() { code = -1, message = "指定Keep-alive標(biāo)頭的請求的連接意外關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.Pending: { //An internal asynchronous request is pending. model = new HttpResultModel() { code = -1, message = "一個內(nèi)部異步請求正在等待處理," + ex.Message }; break; } case WebExceptionStatus.Timeout: { //No response was received during the time-out period for a request. model = new HttpResultModel() { code = -1, message = "在請求的超時期間未收到任何響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.ProxyNameResolutionFailure: { //The name resolver service could not resolve the proxy host name. model = new HttpResultModel() { code = -1, message = "無法解析代理主機名," + ex.Message }; break; } case WebExceptionStatus.UnknownError: { //An exception of unknown type has occurred. model = new HttpResultModel() { code = -1, message = "發(fā)生未知類型的異常," + ex.Message }; break; } case WebExceptionStatus.MessageLengthLimitExceeded: { //A message was received that exceeded the specified limit when sending a request or receiving a response from the server. model = new HttpResultModel() { code = -1, message = "消息的長度超過了允許的最大限制," + ex.Message }; break; } case WebExceptionStatus.CacheEntryNotFound: { //The specified cache entry was not found. model = new HttpResultModel() { code = -1, message = "找不到指定的緩存條目," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByCachePolicy: { //The request was not permitted by the cache policy. In general, this occurs when a request is not cacheable and the effective policy prohibits sending the request to the server. //You might receive this status if a request method implies the presence of a request body, a request method requires direct interaction with the server, or a request contains a conditional header. model = new HttpResultModel() { code = -1, message = "緩存策略不允許該請求," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByProxy: { //This request was not permitted by the proxy. model = new HttpResultModel() { code = -1, message = "代理不允許此請求," + ex.Message }; break; } default: { HttpWebResponse response = (HttpWebResponse)webEx.Response; using (Stream resStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(resStream, encoding)) { result = reader.ReadToEnd().Trim(); } } } break; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } if (string.IsNullOrWhiteSpace(result)) { if (model != null) { result = JsonHelper.SerializeObject(model); } } return result; } /// <summary> /// Post方法 /// </summary> /// <param name="url">請求的地址(不含請求參數(shù))</param> /// <param name="data">請求參數(shù)json字符串</param> /// <param name="authorization">Authorization標(biāo)頭 scheme:認(rèn)證類型 parameter:簽名信息 /// 如:Bearer your_access_token、API-Key your_api_key,微信支付V3的 WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\" /// { scheme = "Bearer", parameter="your_access_token" }、 /// { scheme = "API-Key", parameter="your_api_key" }、 /// { scheme = "WECHATPAY2-SHA256-RSA2048", parameter="mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"" } /// </param> /// <param name="accept">Accept代表發(fā)送端(客戶端)希望接受的數(shù)據(jù)類型。 比如:Accept:text/xml; 代表客戶端希望接受的數(shù)據(jù)類型是xml類型。放在請求頭中。</param> /// <param name="contentType">Content-Type代表發(fā)送端(客戶端|服務(wù)器)發(fā)送的實體數(shù)據(jù)的數(shù)據(jù)類型。</param> /// <param name="encoding"></param> /// <param name="timeOut">默認(rèn)值是 100,000 毫秒(100 秒)</param> /// <returns></returns> public static string HttpPost(string url, string data, HttpAuthorization authorization = null, string accept = "application/json", string contentType = "application/json", Encoding encoding = null, int timeOut = 100) { string result = ""; HttpResultModel model = null; //編碼方式 if (encoding == null) { encoding = Encoding.UTF8; } try { if (_client.BaseAddress is null) { _client.BaseAddress = new Uri(url); } //超時設(shè)置 _client.Timeout = new TimeSpan(timeOut * 1000); //Accept代表發(fā)送端(客戶端)希望接受的數(shù)據(jù)類型 if (!string.IsNullOrWhiteSpace(accept)) { _client.DefaultRequestHeaders.Accept.Clear(); _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); } //Authorization (Bearer) Bearer your_access_token、API-Key your_api_key if (!string.IsNullOrWhiteSpace(authorization)) { _client.DefaultRequestHeaders.Add("Authorization", authorization); } //能解讀https類型 指定 ServicePoint 安全協(xié)議 if (url.StartsWith("https")) { ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; } using (StringContent content = new StringContent(data)) { content.Headers.ContentType = new MediaTypeHeaderValue(contentType); using (HttpResponseMessage response = _client.GetAsync(url).Result) { response.EnsureSuccessStatusCode(); string body = response.Content.ReadAsStringAsync().Result; string serial = response.Headers.GetValues("Wechatpay-Serial").ToString(); string signature = response.Headers.GetValues("Wechatpay-Signature").ToString(); string timestamp = response.Headers.GetValues("Wechatpay-Timestamp").ToString(); string nonce = response.Headers.GetValues("Wechatpay-Nonce").ToString(); //構(gòu)造驗簽名串 string signSource = timestamp + "\n" + nonce + "\n" + body + "\n"; model = new HttpResultModel() { code = 0, message = "成功", data = body, serial = serial, //微信支付V3 驗證簽名時 需要 signature = signature, //微信支付V3 驗證簽名時 需要 signSource = signSource //微信支付V3 驗證簽名時 需要 }; } } } catch (Exception ex) { var actualException = ex.InnerException; if (actualException != null) { if (actualException is SocketException) { model = new HttpResultModel() { code = -1, message = "網(wǎng)絡(luò)中斷," + ex.Message }; } else if (actualException is TimeoutException) { model = new HttpResultModel() { code = -1, message = "連時超時," + ex.Message }; } else if (actualException is WebException webEx) { switch (webEx.Status) { case WebExceptionStatus.NameResolutionFailure: { // DNS 域名解析失敗的處理邏輯 model = new HttpResultModel() { code = -1, message = "無法解析主機名," + ex.Message }; break; } case WebExceptionStatus.ConnectFailure: { //The remote service point could not be contacted at the transport level. model = new HttpResultModel() { code = -1, message = "連接失敗," + ex.Message }; break; } case WebExceptionStatus.RequestCanceled: { //The request was canceled, the System.Net.WebRequest.Abort method was called, or an unclassifiable error occurred. This is the default value for System.Net.WebException.Status. model = new HttpResultModel() { code = -1, message = "請求被取消," + ex.Message }; break; } case WebExceptionStatus.ConnectionClosed: { //The connection was prematurely closed. model = new HttpResultModel() { code = -1, message = "連接關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.ReceiveFailure: { //A complete response was not received from the remote server. model = new HttpResultModel() { code = -1, message = "未收到遠(yuǎn)程服務(wù)器的響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.SendFailure: { //A complete request could not be sent to the remote server. model = new HttpResultModel() { code = -1, message = "無法向遠(yuǎn)程服務(wù)器發(fā)送請求," + ex.Message }; break; } case WebExceptionStatus.PipelineFailure: { //The request was a pipelined request and the connection was closed before the response was received. model = new HttpResultModel() { code = -1, message = "收到響應(yīng)之前關(guān)閉了連接," + ex.Message }; break; } case WebExceptionStatus.ProtocolError: { //The response received from the server was complete but indicated a protocol-level or example, an HTTP protocol error such as 401 Access Denied would use this status. model = new HttpResultModel() { code = -1, message = "HTTP協(xié)議錯誤," + ex.Message }; break; } case WebExceptionStatus.TrustFailure: { //A server certificate could not be validated. model = new HttpResultModel() { code = -1, message = "無法驗證服務(wù)器證書," + ex.Message }; break; } case WebExceptionStatus.SecureChannelFailure: { //An error occurred while establishing a connection using SSL. model = new HttpResultModel() { code = -1, message = "使用SSL建立連接時出錯," + ex.Message }; break; } case WebExceptionStatus.ServerProtocolViolation: { //The server response was not a valid HTTP response. model = new HttpResultModel() { code = -1, message = "服務(wù)器響應(yīng)不是有效的HTTP響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.KeepAliveFailure: { //The connection for a request that specifies the Keep-alive header was closed unexpectedly. model = new HttpResultModel() { code = -1, message = "指定Keep-alive標(biāo)頭的請求的連接意外關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.Pending: { //An internal asynchronous request is pending. model = new HttpResultModel() { code = -1, message = "一個內(nèi)部異步請求正在等待處理," + ex.Message }; break; } case WebExceptionStatus.Timeout: { //No response was received during the time-out period for a request. model = new HttpResultModel() { code = -1, message = "在請求的超時期間未收到任何響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.ProxyNameResolutionFailure: { //The name resolver service could not resolve the proxy host name. model = new HttpResultModel() { code = -1, message = "無法解析代理主機名," + ex.Message }; break; } case WebExceptionStatus.UnknownError: { //An exception of unknown type has occurred. model = new HttpResultModel() { code = -1, message = "發(fā)生未知類型的異常," + ex.Message }; break; } case WebExceptionStatus.MessageLengthLimitExceeded: { //A message was received that exceeded the specified limit when sending a request or receiving a response from the server. model = new HttpResultModel() { code = -1, message = "消息的長度超過了允許的最大限制," + ex.Message }; break; } case WebExceptionStatus.CacheEntryNotFound: { //The specified cache entry was not found. model = new HttpResultModel() { code = -1, message = "找不到指定的緩存條目," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByCachePolicy: { //The request was not permitted by the cache policy. In general, this occurs when a request is not cacheable and the effective policy prohibits sending the request to the server. //You might receive this status if a request method implies the presence of a request body, a request method requires direct interaction with the server, or a request contains a conditional header. model = new HttpResultModel() { code = -1, message = "緩存策略不允許該請求," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByProxy: { //This request was not permitted by the proxy. model = new HttpResultModel() { code = -1, message = "代理不允許此請求," + ex.Message }; break; } default: { HttpWebResponse response = (HttpWebResponse)webEx.Response; using (Stream resStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(resStream, encoding)) { result = reader.ReadToEnd().Trim(); } } } break; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } if (string.IsNullOrWhiteSpace(result)) { if (model != null) { result = JsonHelper.SerializeObject(model); } } return result; } /// <summary> /// POST上傳文件 /// </summary> /// <param name="url">請求的地址</param> /// <param name="filePathList">form-data 文件列表(name,文件路徑)</param> /// <param name="formDataList">form-data 參數(shù)列表(name,文本參數(shù)內(nèi)容)</param> /// <param name="authorization">Authorization標(biāo)頭 scheme:認(rèn)證類型 parameter:簽名信息 /// 如:Bearer your_access_token、API-Key your_api_key,微信支付V3的 WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\" /// { scheme = "Bearer", parameter="your_access_token" }、 /// { scheme = "API-Key", parameter="your_api_key" }、 /// { scheme = "WECHATPAY2-SHA256-RSA2048", parameter="mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"" } /// </param> /// <param name="encoding">編碼方式 默認(rèn)為null時 使用 UTF8</param> /// <param name="timeOut">默認(rèn)值是 100,000 毫秒(100 秒)</param> /// <returns></returns> public static string HttpPostFile(string url, Dictionary<string, string> filePathList, Dictionary<string, string> formDataList = null, HttpAuthorization authorization = null, Encoding encoding = null, int timeOut = 100) { string result = ""; HttpResultModel model = null; //編碼方式 if (encoding == null) { encoding = Encoding.UTF8; } try { if (_client.BaseAddress is null) { _client.BaseAddress = new Uri(url); } //超時設(shè)置 _client.Timeout = new TimeSpan(timeOut * 1000); //Authorization Bearer your_access_token、API-Key your_api_key if (authorization != null) { _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authorization.scheme, authorization.parameter); } //能解讀https類型 指定 ServicePoint 安全協(xié)議 if (url.StartsWith("https")) { ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; } using (var content = new MultipartFormDataContent()) { // 添加表單數(shù)據(jù) if (formDataList != null) { foreach (var keyValuePair in formDataList) { //方法一 //content.Add(new StringContent(keyValuePair.Value, encoding), keyValuePair.Key); //方法二 var byteArrayContent = new ByteArrayContent(encoding.GetBytes(keyValuePair.Value)); byteArrayContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = keyValuePair.Key }; content.Add(byteArrayContent); } } // 添加文件 foreach (var file in filePathList) { //方法一 //content.Add(new ByteArrayContent(File.ReadAllBytes(file.Value)), file.Key, Path.GetFileName(file.Value)); //方法二 var fileContent = new ByteArrayContent(File.ReadAllBytes(file.Value)); fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = file.Key, //接口匹配name FileName = Path.GetFileName(file.Value) //附件文件名 }; } // 發(fā)送請求 using (var response = _client.GetAsync(url).Result) { response.EnsureSuccessStatusCode(); string body = response.Content.ReadAsStringAsync().Result; model = new HttpResultModel() { code = 0, message = "成功", data = body }; } } } catch (Exception ex) { var actualException = ex.InnerException; if (actualException != null) { if (actualException is SocketException) { model = new HttpResultModel() { code = -1, message = "網(wǎng)絡(luò)中斷," + ex.Message }; } else if (actualException is TimeoutException) { model = new HttpResultModel() { code = -1, message = "連時超時," + ex.Message }; } else if (actualException is WebException webEx) { switch (webEx.Status) { case WebExceptionStatus.NameResolutionFailure: { // DNS 域名解析失敗的處理邏輯 model = new HttpResultModel() { code = -1, message = "無法解析主機名," + ex.Message }; break; } case WebExceptionStatus.ConnectFailure: { //The remote service point could not be contacted at the transport level. model = new HttpResultModel() { code = -1, message = "連接失敗," + ex.Message }; break; } case WebExceptionStatus.RequestCanceled: { //The request was canceled, the System.Net.WebRequest.Abort method was called, or an unclassifiable error occurred. This is the default value for System.Net.WebException.Status. model = new HttpResultModel() { code = -1, message = "請求被取消," + ex.Message }; break; } case WebExceptionStatus.ConnectionClosed: { //The connection was prematurely closed. model = new HttpResultModel() { code = -1, message = "連接關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.ReceiveFailure: { //A complete response was not received from the remote server. model = new HttpResultModel() { code = -1, message = "未收到遠(yuǎn)程服務(wù)器的響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.SendFailure: { //A complete request could not be sent to the remote server. model = new HttpResultModel() { code = -1, message = "無法向遠(yuǎn)程服務(wù)器發(fā)送請求," + ex.Message }; break; } case WebExceptionStatus.PipelineFailure: { //The request was a pipelined request and the connection was closed before the response was received. model = new HttpResultModel() { code = -1, message = "收到響應(yīng)之前關(guān)閉了連接," + ex.Message }; break; } case WebExceptionStatus.ProtocolError: { //The response received from the server was complete but indicated a protocol-level or example, an HTTP protocol error such as 401 Access Denied would use this status. model = new HttpResultModel() { code = -1, message = "HTTP協(xié)議錯誤," + ex.Message }; break; } case WebExceptionStatus.TrustFailure: { //A server certificate could not be validated. model = new HttpResultModel() { code = -1, message = "無法驗證服務(wù)器證書," + ex.Message }; break; } case WebExceptionStatus.SecureChannelFailure: { //An error occurred while establishing a connection using SSL. model = new HttpResultModel() { code = -1, message = "使用SSL建立連接時出錯," + ex.Message }; break; } case WebExceptionStatus.ServerProtocolViolation: { //The server response was not a valid HTTP response. model = new HttpResultModel() { code = -1, message = "服務(wù)器響應(yīng)不是有效的HTTP響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.KeepAliveFailure: { //The connection for a request that specifies the Keep-alive header was closed unexpectedly. model = new HttpResultModel() { code = -1, message = "指定Keep-alive標(biāo)頭的請求的連接意外關(guān)閉," + ex.Message }; break; } case WebExceptionStatus.Pending: { //An internal asynchronous request is pending. model = new HttpResultModel() { code = -1, message = "一個內(nèi)部異步請求正在等待處理," + ex.Message }; break; } case WebExceptionStatus.Timeout: { //No response was received during the time-out period for a request. model = new HttpResultModel() { code = -1, message = "在請求的超時期間未收到任何響應(yīng)," + ex.Message }; break; } case WebExceptionStatus.ProxyNameResolutionFailure: { //The name resolver service could not resolve the proxy host name. model = new HttpResultModel() { code = -1, message = "無法解析代理主機名," + ex.Message }; break; } case WebExceptionStatus.UnknownError: { //An exception of unknown type has occurred. model = new HttpResultModel() { code = -1, message = "發(fā)生未知類型的異常," + ex.Message }; break; } case WebExceptionStatus.MessageLengthLimitExceeded: { //A message was received that exceeded the specified limit when sending a request or receiving a response from the server. model = new HttpResultModel() { code = -1, message = "消息的長度超過了允許的最大限制," + ex.Message }; break; } case WebExceptionStatus.CacheEntryNotFound: { //The specified cache entry was not found. model = new HttpResultModel() { code = -1, message = "找不到指定的緩存條目," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByCachePolicy: { //The request was not permitted by the cache policy. In general, this occurs when a request is not cacheable and the effective policy prohibits sending the request to the server. //You might receive this status if a request method implies the presence of a request body, a request method requires direct interaction with the server, or a request contains a conditional header. model = new HttpResultModel() { code = -1, message = "緩存策略不允許該請求," + ex.Message }; break; } case WebExceptionStatus.RequestProhibitedByProxy: { //This request was not permitted by the proxy. model = new HttpResultModel() { code = -1, message = "代理不允許此請求," + ex.Message }; break; } default: { HttpWebResponse response = (HttpWebResponse)webEx.Response; using (Stream resStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(resStream, encoding)) { result = reader.ReadToEnd().Trim(); } } } break; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } else { model = new HttpResultModel() { code = -1, message = ex.Message }; } } if (string.IsNullOrWhiteSpace(result)) { if (model != null) { result = JsonHelper.SerializeObject(model); } } return result; } } /// <summary> /// HTTP請求返回結(jié)果 /// </summary> public class HttpResultModel { /// <summary> /// 請求狀態(tài)碼 0為正確 其他為失敗 /// </summary> public int code { set; get; } /// <summary> /// 請求失敗信息描述 /// </summary> public string message { set; get; } /// <summary> /// 返回的數(shù)據(jù) /// </summary> public string data { set; get; } #region 微信支付V3版本需要返回的信息 /// <summary> /// 請求返回的平臺證書序列號 /// </summary> public string serial { set; get; } /// <summary> /// 請求返回的應(yīng)答簽名 /// </summary> public string signature { set; get; } /// <summary> /// 應(yīng)答時間戳 應(yīng)答隨機串 /// <summary> public string signSource { set; get; } /// <summary> /// 詳細(xì)錯誤碼 /// </summary> public HttpResultDetail detail { set; get; } #endregion 微信支付V3版本需要返回的信息 } /// <summary> /// 微信支付V3版本返回詳細(xì)錯誤碼 /// </summary> public class HttpResultDetail { /// <summary> /// 指示錯誤參數(shù)的位置。當(dāng)錯誤參數(shù)位于請求body的JSON時,填寫指向參數(shù)的JSON Pointer 。當(dāng)錯誤參數(shù)位于請求的url或者querystring時,填寫參數(shù)的變量名。 /// </summary> public string field { set; get; } /// <summary> /// 錯誤的值 /// </summary> public string value { set; get; } /// <summary> /// 具體錯誤原因 /// </summary> public string issue { set; get; } /// <summary> /// /// </summary> public string location { set; get; } } /// <summary> /// HTTP請求頭認(rèn)證信息 /// </summary> public class HttpAuthorization { /// <summary> /// 認(rèn)證類型 /// </summary> public string scheme { set; get; } /// <summary> /// 簽名信息 /// </summary> public string parameter { set; get; } }
/// <summary> /// 生成隨機字符串 /// </summary> /// <param name="length">要生成字符串的長度</param> /// <returns></returns> public static string GetRandomString(int length) { char[] _characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray(); Random random = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.Append(_characters[random.Next(_characters.Length)]); } return sb.ToString(); }
調(diào)用方法:
(1)微信支付V3版本API調(diào)用方式:
string merchantId = ""; //微信支付商戶號mchid string nonce_str = ""; //請求隨機串nonce_str string timestamp = ""; //時間戳timestamp string serialNo = ""; //商戶API證書序列號serial_no string signature = ""; //簽名值signature string userAgent = string.Format("TenPay/V3 {0}", merchantId); HttpAuthorization authorization = new HttpAuthorization(); authorization.scheme = "WECHATPAY2-SHA256-RSA2048"; authorization.parameter = string.Format("mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"", merchantId, nonce_str, timestamp, serialNo, signature); HttpClientService.GetInstance(); string result = HttpClientService.HttpGet(url, authorization, userAgent);
(2)Bearer 認(rèn)證的調(diào)用方式:
HttpAuthorization authorization = new HttpAuthorization(); authorization.scheme = "Bearer"; authorization.parameter = "your_access_token"; HttpClientService.GetInstance(); string result = HttpClientService.HttpGet(url, authorization);
(3)其他自定義認(rèn)證的調(diào)用方式:
HttpAuthorization authorization = new HttpAuthorization(); authorization.scheme = "API-Key"; authorization.parameter = "your_api_key"; HttpClientService.GetInstance(); string result = HttpClientService.HttpGet(url, authorization);
浙公網(wǎng)安備 33010602011771號