Пример #1
0
 /// <summary>
 /// 封装HttpOption的Send扩展方法发送HTTP请求,并提供失败重试功能。
 /// 如果遇到WebException异常,就转换成RemoteWebException异常
 /// </summary>
 /// <param name="option">HttpOption实例,用于包含HTTP请求的发送参数</param>
 /// <param name="retry">提供一个Retry实例,用于指示如何执行重试。如果此参数为NULL则不启用重试</param>
 /// <returns></returns>
 public static T GetResult <T>(this HttpOption option, Retry retry = null)
 {
     try {
         if (retry == null)
         {
             return(option.Send <T>());
         }
         else
         {
             return(retry.Run(option.Send <T>));
         }
     }
     catch (WebException ex) {
         // 返回一个容易获取异常消息的异常类型
         throw new RemoteWebException(ex, option.Url);
     }
 }
Пример #2
0
        /// <summary>
        /// 封装HttpOption的Send扩展方法发送HTTP请求,并提供失败重试功能。
        /// 如果遇到WebException异常,就转换成RemoteWebException异常
        /// </summary>
        /// <param name="option">HttpOption实例,用于包含HTTP请求的发送参数</param>
        /// <param name="retry">提供一个Retry实例,用于指示如何执行重试。如果此参数为NULL将采用默认重试规则</param>
        /// <returns></returns>
        public static T GetResult <T>(this HttpOption option, Retry retry)
        {
            if (retry == null)
            {
                retry = GetDefaultRetry();
            }

            try {
                return(retry.Run <T>(() => {
                    return option.Send <T>();
                }));
            }
            catch (WebException ex) {
                // 返回一个容易获取异常消息的异常类型
                throw new RemoteWebException(ex);
            }
        }
Пример #3
0
 /// <summary>
 /// 封装HttpOption的Send扩展方法发送HTTP请求,并提供失败重试功能。
 /// 如果遇到WebException异常,就转换成RemoteWebException异常
 /// </summary>
 /// <param name="option">HttpOption实例,用于包含HTTP请求的发送参数</param>
 /// <param name="retry">提供一个Retry实例,用于指示如何执行重试。如果此参数为NULL则不启用重试</param>
 /// <returns></returns>
 public async static Task <string> GetResultAsync(this HttpOption option, Retry retry = null)
 {
     try {
         if (retry == null)
         {
             return(await option.SendAsync());
         }
         else
         {
             return(await retry.RunAsync(option.SendAsync));
         }
     }
     catch (WebException ex) {
         // 返回一个容易获取异常消息的异常类型
         throw new RemoteWebException(ex, option.Url);
     }
 }
Пример #4
0
        /// <summary>
        /// 封装HttpOption的Send扩展方法发送HTTP请求,并提供失败重试功能。
        /// 如果遇到WebException异常,就转换成RemoteWebException异常
        /// </summary>
        /// <param name="option">HttpOption实例,用于包含HTTP请求的发送参数</param>
        /// <param name="retry">提供一个Retry实例,用于指示如何执行重试。如果此参数为NULL将采用默认重试规则</param>
        /// <returns></returns>
        public async static Task <string> GetResultAsync(this HttpOption option, Retry retry)
        {
            if (retry == null)
            {
                retry = GetDefaultRetry();
            }

            try {
                return(await retry.RunAsync <string>(async() => {
                    return await option.SendAsync();
                }));
            }
            catch (WebException ex) {
                // 返回一个容易获取异常消息的异常类型
                throw new RemoteWebException(ex);
            }
        }
Пример #5
0
        /// <summary>
        /// 根据指定的HttpOption参数,用【异步】方式发起一次HTTP请求
        /// </summary>
        /// <typeparam name="T">返回值的类型参数</typeparam>
        /// <param name="option">HttpOption的实例,用于描述请求参数</param>
        /// <returns>返回服务端的调用结果,并转换成指定的类型</returns>
        public async static Task <T> SendAsync <T>(this HttpOption option)
        {
            if (option == null)
            {
                throw new ArgumentNullException("option");
            }

            option.CheckInput();



            HttpClient client   = ObjectFactory.New <HttpClient>();
            bool       urlQuery = option.IsMustQueryString();

            string requestUrl = option.Url;

            if (option.Data != null && urlQuery)                //GET 请求,需要将参数合并到URL,形成查询字符串参数
            {
                if (option.Url.IndexOf('?') < 0)
                {
                    requestUrl = option.Url + "?" + GetQueryString(option.Data);
                }
                else
                {
                    requestUrl = option.Url + "&" + GetQueryString(option.Data);
                }
            }

            HttpWebRequest request = client.CreateWebRequest(requestUrl);

            SetWebRequest(request, option);

            option.SetRequestAction?.Invoke(request);                   // 调用委托

            if (option.Data != null && urlQuery == false)               // POST提交数据
            {
                await client.SetRequestDataAsync(option.Data, option.Format);
            }

            using (HttpWebResponse response = await client.GetResponseAsync()) {
                option.ReadResponseAction?.Invoke(response);                    // 调用委托

                return(client.GetResult <T>(response));
            }
        }
Пример #6
0
        private static void SetWebRequest(HttpWebRequest request, HttpOption option)
        {
            request.Method = option.Method;

            foreach (NameValue item in option.Headers)
            {
                request.Headers.InternalAdd(item.Name, item.Value);
            }

            if (option.Cookie != null)
            {
                request.CookieContainer = option.Cookie;
            }

            if (option.Credentials != null)
            {
                request.Credentials = option.Credentials;                               // CredentialCache.DefaultCredentials;
            }
            if (option.Timeout.HasValue)
            {
                request.Timeout = option.Timeout.Value;
            }

            if (string.IsNullOrEmpty(option.ContentType) == false)
            {
                request.ContentType = option.ContentType;
            }

            if (string.IsNullOrEmpty(option.UserAgent) == false)
            {
                request.UserAgent = option.UserAgent;
            }

            if (option.DisableAutoRedirect)
            {
                request.AllowAutoRedirect = false;
            }
        }
Пример #7
0
        /// <summary>
        /// 根据原始请求信息文本构建 HttpOption 对象(格式可参考Fiddler的Inspectors标签页内容)
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static HttpOption FromRawText(string text)
        {
            // 示例数据:
            //POST http://www.fish-mvc-demo.com/Ajax/ns/TestAutoAction/submit.aspx HTTP/1.1
            //Host: www.fish-mvc-demo.com
            //User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
            //Accept: */*
            //Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
            //Accept-Encoding: gzip, deflate
            //Content-Type: application/x-www-form-urlencoded; charset=UTF-8
            //X-Requested-With: XMLHttpRequest
            //Referer: http://www.fish-mvc-demo.com/Pages/Demo/TestAutoFindAction.htm
            //Content-Length: 72
            //Cookie: hasplmlang=_int_; LoginBy=productKey; PageStyle=Style2;
            //Connection: keep-alive
            //Pragma: no-cache
            //Cache-Control: no-cache

            //input=Fish+Li&Base64=%E8%BD%AC%E6%8D%A2%E6%88%90Base64%E7%BC%96%E7%A0%81

            if (string.IsNullOrEmpty(text))
            {
                throw new ArgumentNullException("text");
            }

            HttpOption option = new HttpOption();

            option.ContentType = null;


            using (StringReader reader = new StringReader(text.Trim())) {
                string firstLine = reader.ReadLine();

                int p1 = firstLine.IndexOf(' ');
                int p2 = firstLine.LastIndexOf(' ');

                if (p1 < 0 || p1 == p2)
                {
                    throw new ArgumentException("不能识别的请求文本格式。");
                }


                option.Method = firstLine.Substring(0, p1);

                // 不使用HTTP协议版本,只做校验。
                string httpVersion = firstLine.Substring(p2 + 1);
                if (httpVersion.StartsWith("HTTP/") == false)
                {
                    throw new ArgumentException("不能识别的请求文本格式。");
                }

                option.Url = firstLine.Substring(p1 + 1, p2 - p1 - 1);

                string line = null;
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Length > 0)
                    {
                        // 处理请求头
                        int p3 = line.IndexOf(':');
                        if (p3 > 0)
                        {
                            string name  = line.Substring(0, p3);
                            string value = line.Substring(p3 + 2);                              // 2 表示2个字符,一个冒号,一个空格
                            option.Headers.Add(name, value);
                        }
                        else
                        {
                            throw new ArgumentException("不能识别的请求文本格式。");
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                // 请求体数据
                string postText = reader.ReadToEnd();
                if (string.IsNullOrEmpty(postText) == false)
                {
                    option.Data = postText;
                }
            }


            string contentType = option.Headers["Content-Type"];

            if (contentType != null)
            {
                int p = contentType.IndexOf("; charset=");
                // 注意:这里丢弃了 charset 设置,因为 HttpClient 固定以 utf-8 编码方式发送请求!
                if (p > 0)
                {
                    option.ContentType = contentType.Substring(0, p);
                }
                else
                {
                    option.ContentType = contentType;
                }

                option.Headers.Remove("Content-Type");
            }

            return(option);
        }
Пример #8
0
 /// <summary>
 /// 根据指定的HttpOption参数,用【异步】方式发起一次HTTP请求
 /// </summary>
 /// <param name="option">HttpOption的实例,用于描述请求参数</param>
 /// <returns>返回服务端的调用结果,并转换成指定的类型</returns>
 public async static Task <string> SendAsync(this HttpOption option)
 {
     return(await SendAsync <string>(option));
 }
Пример #9
0
 /// <summary>
 /// 根据指定的HttpOption参数,用【同步】方式发起一次HTTP请求
 /// </summary>
 /// <param name="option">HttpOption的实例,用于描述请求参数</param>
 /// <returns>返回服务端的调用结果,并转换成指定的类型</returns>
 public static string Send(this HttpOption option)
 {
     return(Send <string>(option));
 }