zoukankan      html  css  js  c++  java
  • WebApi 异步请求(HttpClient)

    还是那几句话:

    学无止境,精益求精

    十年河东,十年河西,莫欺少年穷

    学历代表你的过去,能力代表你的现在,学习代表你的将来

    废话不多说,直接进入正题:

    今天公司总部要求各个分公司把短信接口对接上,所谓的短信接口其实就是GET或者Post请求,接到这个任务感觉好Easy。

    但是真正写起来,你会发现各种各样的问题,比如请求报401错误,报400错误,报..等等各种意想不到的错误!总之,在这个过程中尝试了三个方法:

    第一个方法如下(由于第一个方法封装的比较多,在此仅仅截图),如下:

    小矩形内得POST方法,结果发现报400错误。

    紧接着我又尝试了第二种方法(这种方法比较简单,一般的POST请求都可以完成)

    第二种方法如下(2014年微信公众号开发中,好多请求我都用的这个方法):

    public static string GetPage(string posturl, string postData)
            {
                //WX_SendNews news = new WX_SendNews(); 
                //posturl: news.Posturl;
                //postData:news.PostData;
                System.IO.Stream outstream = null;
                Stream instream = null;
                StreamReader sr = null;
                HttpWebResponse response = null;
                HttpWebRequest request = null;
                Encoding encoding = Encoding.UTF8;
                byte[] data = encoding.GetBytes(postData);
                // 准备请求...  
                try
                {
                    // 设置参数  
                    request = WebRequest.Create(posturl) as HttpWebRequest;
                    CookieContainer cookieContainer = new CookieContainer();
                    request.CookieContainer = cookieContainer;
                    request.AllowAutoRedirect = true;
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = data.Length;
                    outstream = request.GetRequestStream();
                    outstream.Write(data, 0, data.Length);
                    outstream.Close();
                    //发送请求并获取相应回应数据  
                    response = request.GetResponse() as HttpWebResponse;
                    //直到request.GetResponse()程序才开始向目标网页发送Post请求  
                    instream = response.GetResponseStream();
                    sr = new StreamReader(instream, encoding);
                    //返回结果网页(html)代码  
                    string content = sr.ReadToEnd();
                    string err = string.Empty;
    
                    return content;
                }
                catch (Exception ex)
                {
                    string err = ex.Message;
                    return string.Empty;
                }
            }
    View Code

    结果这个方法报401错误。

    无奈,又在Git Hub上找了个方法,如下:

    /*
     * Created by SharpDevelop.
     * User: RedXu
     * Date: 2015-04-16
     * Time: 13:58
     * 
     */
    using System;
    using System.Net;
    using System.IO;
    using System.Text;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    
    namespace RedXuCSharpClass
    {
        /// <summary>
        /// Http操作类.
        /// </summary>
        public class HttpHelper
        {
            private const int ConnectionLimit = 100;
            //编码
            private Encoding _encoding = Encoding.Default;
            //浏览器类型
            private string[] _useragents = new string[]{
                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)",
                "Mozilla/5.0 (Windows NT 6.1; rv:36.0) Gecko/20100101 Firefox/36.0",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0"
            };
    
            private String _useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36";
            //接受类型
            private String _accept = "text/html, application/xhtml+xml, application/xml, */*";
            //超时时间
            private int _timeout = 30 * 1000;
            //类型
            private string _contenttype = "application/x-www-form-urlencoded";
            //cookies
            private String _cookies = "";
            //cookies
            private CookieCollection _cookiecollection;
            //custom heads
            private Dictionary<string, string> _headers = new Dictionary<string, string>();
    
            public HttpHelper()
            {
                _headers.Clear();
                //随机一个useragent
                _useragent = _useragents[new Random().Next(0, _useragents.Length)];
                //解决性能问题?
                ServicePointManager.DefaultConnectionLimit = ConnectionLimit;
            }
    
            public void InitCookie()
            {
                _cookies = "";
                _cookiecollection = null;
                _headers.Clear();
            }
    
            /// <summary>
            /// 设置当前编码
            /// </summary>
            /// <param name="en"></param>
            public void SetEncoding(Encoding en)
            {
                _encoding = en;
            }
    
            /// <summary>
            /// 设置UserAgent
            /// </summary>
            /// <param name="ua"></param>
            public void SetUserAgent(String ua)
            {
                _useragent = ua;
            }
    
            public void RandUserAgent()
            {
                _useragent = _useragents[new Random().Next(0, _useragents.Length)];
            }
    
            public void SetCookiesString(string c)
            {
                _cookies = c;
            }
    
            /// <summary>
            /// 设置超时时间
            /// </summary>
            /// <param name="sec"></param>
            public void SetTimeOut(int msec)
            {
                _timeout = msec;
            }
    
            public void SetContentType(String type)
            {
                _contenttype = type;
            }
    
            public void SetAccept(String accept)
            {
                _accept = accept;
            }
    
            /// <summary>
            /// 添加自定义头
            /// </summary>
            /// <param name="key"></param>
            /// <param name="ctx"></param>
            public void AddHeader(String key, String ctx)
            {
                //_headers.Add(key,ctx);
                _headers[key] = ctx;
            }
    
            /// <summary>
            /// 清空自定义头
            /// </summary>
            public void ClearHeader()
            {
                _headers.Clear();
            }
    
            /// <summary>
            /// 获取HTTP返回的内容
            /// </summary>
            /// <param name="response"></param>
            /// <returns></returns>
            private String GetStringFromResponse(HttpWebResponse response)
            {
                String html = "";
                try
                {
                    Stream stream = response.GetResponseStream();
                    StreamReader sr = new StreamReader(stream, _encoding);
                    html = sr.ReadToEnd();
    
                    sr.Close();
                    stream.Close();
                }
                catch (Exception e)
                {
                    Trace.WriteLine("GetStringFromResponse Error: " + e.Message);
                }
    
                return html;
            }
    
            /// <summary>
            /// 检测证书
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="certificate"></param>
            /// <param name="chain"></param>
            /// <param name="errors"></param>
            /// <returns></returns>
            private bool CheckCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                return true;
            }
    
            /// <summary>
            /// 发送GET请求
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public String HttpGet(String url)
            {
                return HttpGet(url, url);
            }
    
    
            /// <summary>
            /// 发送GET请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="refer"></param>
            /// <returns></returns>
            public String HttpGet(String url, String refer)
            {
                String html;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "GET";
                    request.Referer = refer;
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.UnsafeAuthenticatedConnectionSharing = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                        {
                            c.Domain = request.Host;
                        }
    
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    html = GetStringFromResponse(response);
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
    
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        string tmpcookie = response.Headers["Set-Cookie"];
                        _cookiecollection.Add(ConvertCookieString(tmpcookie));
                    }
    
                    response.Close();
                    return html;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpGet Error: " + e.Message);
                    return String.Empty;
                }
            }
    
            /// <summary>
            /// 获取MINE文件
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public Byte[] HttpGetMine(String url)
            {
                Byte[] mine = null;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "GET";
                    request.Referer = url;
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.UnsafeAuthenticatedConnectionSharing = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                            c.Domain = request.Host;
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream stream = response.GetResponseStream();
                    MemoryStream ms = new MemoryStream();
    
                    byte[] b = new byte[1024];
                    while (true)
                    {
                        int s = stream.Read(b, 0, b.Length);
                        ms.Write(b, 0, s);
                        if (s == 0 || s < b.Length)
                        {
                            break;
                        }
                    }
                    mine = ms.ToArray();
                    ms.Close();
    
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
    
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        _cookies = response.Headers["Set-Cookie"];
                    }
    
                    stream.Close();
                    stream.Dispose();
                    response.Close();
                    return mine;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpGetMine Error: " + e.Message);
                    return null;
                }
            }
    
            /// <summary>
            /// 发送POST请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public String HttpPost(String url, String data)
            {
                return HttpPost(url, data, url);
            }
    
            /// <summary>
            /// 发送POST请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="data"></param>
            /// <param name="refer"></param>
            /// <returns></returns>
            public String HttpPost(String url, String data, String refer)
            {
                String html;
                try
                {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = _useragent;
                    request.Timeout = _timeout;
                    request.Referer = refer;
                    request.ContentType = _contenttype;
                    request.Accept = _accept;
                    request.Method = "POST";
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = true;
                    request.CookieContainer = new CookieContainer();
                    //据说能提高性能
                    request.Proxy = null;
    
                    if (_cookiecollection != null)
                    {
                        foreach (Cookie c in _cookiecollection)
                        {
                            c.Domain = request.Host;
                            if (c.Domain.IndexOf(':') > 0)
                                c.Domain = c.Domain.Remove(c.Domain.IndexOf(':'));
                        }
                        request.CookieContainer.Add(_cookiecollection);
                    }
    
                    foreach (KeyValuePair<String, String> hd in _headers)
                    {
                        request.Headers[hd.Key] = hd.Value;
                    }
                    byte[] buffer = _encoding.GetBytes(data.Trim());
                    request.ContentLength = buffer.Length;
                    request.GetRequestStream().Write(buffer, 0, buffer.Length);
                    request.GetRequestStream().Close();
    
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    html = GetStringFromResponse(response);
                    if (request.CookieContainer != null)
                    {
                        response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
                    }
                    if (response.Cookies != null)
                    {
                        _cookiecollection = response.Cookies;
                    }
                    if (response.Headers["Set-Cookie"] != null)
                    {
                        string tmpcookie = response.Headers["Set-Cookie"];
                        _cookiecollection.Add(ConvertCookieString(tmpcookie));
                    }
    
                    response.Close();
                    return html;
                }
                catch (Exception e)
                {
                    Trace.WriteLine("HttpPost Error: " + e.Message);
                    return String.Empty;
                }
            }
    
    
            public string UrlEncode(string str)
            {
                StringBuilder sb = new StringBuilder();
                byte[] byStr = _encoding.GetBytes(str);
                for (int i = 0; i < byStr.Length; i++)
                {
                    sb.Append(@"%" + Convert.ToString(byStr[i], 16));
                }
    
                return (sb.ToString());
            }
    
            /// <summary>
            /// 转换cookie字符串到CookieCollection
            /// </summary>
            /// <param name="ck"></param>
            /// <returns></returns>
            private CookieCollection ConvertCookieString(string ck)
            {
                CookieCollection cc = new CookieCollection();
                string[] cookiesarray = ck.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < cookiesarray.Length; i++)
                {
                    string[] cookiesarray_2 = cookiesarray[i].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    for (int j = 0; j < cookiesarray_2.Length; j++)
                    {
                        string[] cookiesarray_3 = cookiesarray_2[j].Trim().Split("=".ToCharArray());
                        if (cookiesarray_3.Length == 2)
                        {
                            string cname = cookiesarray_3[0].Trim();
                            string cvalue = cookiesarray_3[1].Trim();
                            if (cname.ToLower() != "domain" && cname.ToLower() != "path" && cname.ToLower() != "expires")
                            {
                                Cookie c = new Cookie(cname, cvalue);
                                cc.Add(c);
                            }
                        }
                    }
                }
    
                return cc;
            }
    
    
            public void DebugCookies()
            {
                Trace.WriteLine("**********************BEGIN COOKIES*************************");
                foreach (Cookie c in _cookiecollection)
                {
                    Trace.WriteLine(c.Name + "=" + c.Value);
                    Trace.WriteLine("Path=" + c.Path);
                    Trace.WriteLine("Domain=" + c.Domain);
                }
                Trace.WriteLine("**********************END COOKIES*************************");
            }
    
        }
    }
    View Code

    结果又是没能跳出错误的怪圈,依然是401错误。

    于是,我不得不温习下 C#  HttpClient  的相关方法

    最后,还好,在公司的项目中有这种用到  HttpClient 的方法,于是抱着尝试的心里,作了测试,结果成功了!

    本人写这篇博客也是做一个记录,方便自己以后用,也方便大家遇到 WebApi请求失败时,可以尝试上述的几种方法。

    代码如下:

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KMHC.Infrastructure
    {
        public class SmsSendHelper
        {
            public string _appKey = "";
            public string _category = "";
            public string _templateNo = "";
            public string _templateid = "";
            public SmsSendHelper() { }
            public async Task<SmsSendResult> Send(string phone, string sendContent)
            {
                var Model = BuildData(phone, sendContent);
                SmsSendResult Result = new SmsSendResult();
                var hh = new HttpClient() { BaseAddress = new Uri(SmsUri.SmsSendUri), Timeout = TimeSpan.FromMinutes(30) };
                //Model 需要序列化的对象 
                var res = await hh.PostAsJsonAsync("", Model);
                if (res.StatusCode == HttpStatusCode.OK)
                {
                    var response = res.Content.ReadAsAsync<SmsSendResult>().Result;
                    return response;
                }
                return null;
            }
    
            /// <summary>
            /// 构建请求实体
            /// </summary>
            /// <param name="_phone"></param>
            /// <param name="_sendContent"></param>
            /// <returns></returns>
            private object BuildData(string _phone, string _sendContent)
            {
                var para = new
                {
                    appKey = _appKey,
                    category = _category,
                    templateNo = _templateNo,
                    templateid = _templateid,
                    phone = _phone,
                    sendContent = _sendContent
                };
                return para;
            }
        }
    }
    View Code
            [Route("test"), HttpGet, AllowAnonymous]
            public async Task<IHttpActionResult> test()
            {
                SmsSendHelper Func = new SmsSendHelper();
                var data =await Func.Send("181XXXX0152","你好!短信测试。");
                return Ok(data);
            }
    View Code

    需要引用如下命名空间:

    总之,很简单,也很好用。

     @陈卧龙的博客

  • 相关阅读:
    Webpack4不求人(5) ——编写自定义插件
    Webpack4不求人(4)——编写自定义Loader
    Webpack4不求人(3) ——性能优化
    Webpack4不求人(2) ——手把手搭建TypeScript+React16+ReactRouter5同构应用脚手架
    Shell脚本快速入门(1)
    kafka二进制协议分析与PHP客户端开发
    深入浅出ES6的标准内置对象Proxy
    ES6的Set类型
    深入浅出ES6的迭代器
    Javascript事件系统
  • 原文地址:https://www.cnblogs.com/chenwolong/p/Web.html
Copyright © 2011-2022 走看看