开发者社区> 问答> 正文

.Net 下2种方式实现HTTP同步异步需要4.6.1源码附带token管理

第一种,原始方式实现(同步异步).
/// <summary>
    /// http网络通信
    /// 不实用大文件读取下载
    /// </summary>
    public static class HttpHelper
    {
       private static IDictionary<string, string> headers = new Dictionary<string, string>();
       /// <summary>
       /// 添加网络头
       /// </summary>
       /// <param name="key"></param>
       /// <param name="value"></param>
       public static void AddHeader(string key,string value) {
           if (!headers.Keys.Contains(key))
               headers.Add(key, value);
       }
       /// <summary>
       /// 设置网络头
       /// </summary>
       /// <param name="headers"></param>
       public static void SetHeader(IDictionary<string, string> header) {
           headers = header;
       }
        /// <summary>
        /// 保存cookie信息
        /// </summary>
        private static CookieContainer myCookieContainer = new CookieContainer();
        #region 同步方式
        /// <summary>
        /// 基础网络流
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <param name="hasCookie"></param>
        /// <param name="method"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static Stream RequstBase(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json")
       {
            Stream result = new MemoryStream();
           HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            //添加http头
           if (headers != null && headers.Count() > 0)
           {
               foreach (var h in headers) {
                   try
                   {
                       request.Headers.Add(h.Key, h.Value);
                   }
                   catch { }
               }

           }
           request.Method = method;
           if (hasCookie) request.CookieContainer = myCookieContainer;
           if (!string.IsNullOrEmpty(data) && method.ToUpper() == "POST")
           {
               request.ContentType = contentType;
               var dataBuffer = UTF8Encoding.UTF8.GetBytes(data);
               request.ContentLength = dataBuffer.Length;
               var reStream = request.GetRequestStream();
               reStream.Write(dataBuffer, 0, dataBuffer.Length);
           }
           else
           {
               request.ContentLength = 0;
           }
           WebResponse response = null;
           try
           {
               response = request.GetResponse();
               if (!request.HaveResponse)
               {
                   response.Close();
                   return result;
               }
               //将数据一次性全部读取到内存
               //下载大文件时候需要改进
                var c = 1;
                var stream = response.GetResponseStream();
                while (c > 0) {
                    byte[] buffer = new byte[1024];
                    c = stream.Read(buffer, 0, buffer.Length);
                    result.Write(buffer, 0, buffer.Length);
                }
                result.Position = 0;
           }
           catch (Exception ex)
           {
               return result;
           }
           finally
           {
               if(headers!=null&headers.Count()>0)
                   headers.Clear();
                if (response != null) response.Close();
            }
           return result;
       }
       /// <summary>
       /// 字符串获取
       /// </summary>
       /// <param name="url"></param>
       /// <param name="data"></param>
       /// <param name="hasCookie"></param>
       /// <param name="method"></param>
       /// <param name="contentType"></param>
       /// <returns></returns>

       public static string StringRequst(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json")
        {
            string result = string.Empty;
            var stream=RequstBase( url,  data ,  hasCookie,  method ,  contentType);
            if (stream != null)
                result = stream.ToStr();
            return result;
        }
       /// <summary>
       /// 获取网络对象
       /// </summary>
       /// <typeparam name="T"></typeparam>
       /// <param name="url"></param>
       /// <param name="data"></param>
       /// <param name="hasCookie"></param>
       /// <param name="method"></param>
       /// <param name="contentType"></param>
       /// <returns></returns>
       public static T Request<T>(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json") {
           T result = default(T);
           var stream = StringRequst(url, data, hasCookie, method, contentType);
           if (!string.IsNullOrEmpty(stream))
               result = stream.ToObject<T>();
           return result;
       }

        #endregion
        /// <summary>
        /// 转换为string
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static string ToStr(this Stream stream)
       {
           return stream.ReadToEnd();
       }

        #region 异步方式
        public async static Task<Stream> RequstBaseAsync(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json") {
            Stream result = new MemoryStream();
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            //添加http头
            if (headers != null && headers.Count() > 0)
            {
                foreach (var h in headers)
                {
                    try
                    {
                        request.Headers.Add(h.Key, h.Value);
                    }
                    catch { }
                }

            }
            request.Method = method;
            if (hasCookie) request.CookieContainer = myCookieContainer;
            if (!string.IsNullOrEmpty(data) && method.ToUpper() == "POST")
            {
                request.ContentType = contentType;
                var dataBuffer = UTF8Encoding.UTF8.GetBytes(data);
                request.ContentLength = dataBuffer.Length;
                var reStream = request.GetRequestStream();
                reStream.Write(dataBuffer, 0, dataBuffer.Length);
            }
            else
            {
                request.ContentLength = 0;
            }
            WebResponse response = null;
            try
            {
                response =await request.GetResponseAsync();
                if (!request.HaveResponse)
                {
                    response.Close();
                    return result;
                }
                //将数据一次性全部读取到内存
                //下载大文件时候需要改进
                var c = 1;
                var stream =response.GetResponseStream();
                while (c > 0)
                {
                    byte[] buffer = new byte[1024];
                    c =await stream.ReadAsync(buffer, 0, buffer.Length);
                    await result.WriteAsync(buffer, 0,c);
                }
                result.Position = 0;
            }
            catch (Exception ex)
            {
                return result;
            }
            finally
            {
                if (headers != null & headers.Count() > 0)
                    headers.Clear();
                if (response != null) response.Close();
            }
            return result;

        }

        public async static Task<string> StringRequstAsync(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json")
        {
            string result = string.Empty;
            var stream =await RequstBaseAsync(url, data, hasCookie, method, contentType);
            if (stream != null)
                result = stream.ToStr();
            return result;
        }
        public async static Task<T> RequestAsync<T>(string url, string data = "", bool hasCookie = true, string method = "Post", string contentType = "application/json")
        {
            T result = default(T);
            var stream =await StringRequstAsync(url, data, hasCookie, method, contentType);
            if (!string.IsNullOrEmpty(stream))
                result = stream.ToObject<T>();
            return result;
        }
        #endregion
第二种简单模式(只异步)

public static class Http
    {
        public static async Task<string> Post(string url, IEnumerable<KeyValuePair<string, string>> data = null, IDictionary<string, string> header = null)
        {
            try
            {
                HttpClient http = new HttpClient();
                if (header != null && header.Any())
                {
                    foreach (var kv in header)
                        http.DefaultRequestHeaders.Add(kv.Key, kv.Value);

                }
                var result = await http.PostAsync(url, new FormUrlEncodedContent(data));
                return await result.Content.ReadAsStringAsync();
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        public static async Task<T> Post<T>(string url, IEnumerable<KeyValuePair<string, string>> data = null, IDictionary<string, string> header = null)
        {
            var result = await Post(url, data, header);
            return result.ToObject<T>();
        }

    }
代码拷贝就能用.
其中没有贴出来扩展方法.有点多,分插件了.需要我再贴.


token 自动管理类,其中需要自己完成部分实体,根据你项目定义的不一样.
该类可以解决多线程情况异步模式下的问题


    public class TokenContainer
    {
        private static string tokenUri = "account/token";//token的获取地址
        private static Token _Token { get; set; } = new Token();
        private readonly static object locked = new object();
        private static DateTime Expiress { get; set; } = DateTime.Now;
        public static async Task<Token> Get() {
            if (_Token == null|| Expiress<=DateTime.Now)
                lock (locked) {
                    if (_Token == null || Expiress <= DateTime.Now)
                    {
                        if (string.IsNullOrEmpty(Config.UserName) || string.IsNullOrEmpty(Config.Password))//相关配置信息
                            throw new Exception("必须提供用户名密码");
                        var parames = ParameterHelper.Create();
                        parames.Add("username", Config.UserName);
                        parames.Add("password",Config.Password);
                        var result = Http.Post<TokenResult>($"{Config.BaseUrl}{tokenUri}", parames.ToKeyPar()).Result; ;
                        if (result.s)
                        { _Token = result.d; Expiress = DateTime.Now.AddMinutes(result.d.Expiress); }
                    }
                }
            return await Task.FromResult( _Token);
        }

    }

展开
收起
欧阳寒玟 2016-05-07 05:10:41 5852 0
1 条回答
写回答
取消 提交回答
  • 不错不错
    2016-05-08 20:49:00
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
阿里巴巴HTTP 2.0实践及无线通信协议的演进之路 立即下载
CDN助力企业网站进入HTTPS时代 立即下载
《基于 Service Worker 实现在线代理》 立即下载