[C # programming best practices for how to send twenty] Http request with a retry mechanism

Recently doing a function is invoked to send a Http request by ESB client http learn the relevant invocation, how to send a request with a retry mechanism of it?

HttpClient initialization

Throughout the call, the way we used to delegate method, joined the sleep mechanism retry mechanism and thread in the outer layer of trust in . Then call the delegate method is divided into POST and Get, and I also used to return the results of a generic way to define class response, including the success or failure of response status code.

    /// <summary>
    /// 用于访问Rest接口(访问站点的请求)
    /// </summary>
    public class HttpClientHelper
    {
        #region 日志及单例

        protected static readonly LogWrapper Logger = new LogWrapper();

        #endregion 日志及单例

        #region 委托方式进行重试调用

        public static TResult ExecuteFunc<TResult>(Func<TResult> target, int retryCount = 5, int current = 1, int sleepMilliseconds = 0)
        {
            try
            {
                return target.Invoke();
            }
            catch (Exception)
            {
                //超过重试次数后抛出异常
                if (retryCount - current <= 0)
                {
                    throw;
                }
                if (sleepMilliseconds > 0)
                {
                    Thread.Sleep(sleepMilliseconds);
                }
            }
            //递归调用直至超出重试次数后抛出异常
            return ExecuteFunc(target, retryCount, current + 1, sleepMilliseconds);
        }

        #endregion 委托方式进行重试调用

        #region POST及GET请求方法

        /// <summary>
        /// 通过post请求数据
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <typeparam name="TData"></typeparam>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static ApiResult<TResult> Post<TResult, TData>(string url, TData data)
        {
            //获取请求数据
            var value = data == null ? string.Empty : JsonConvert.SerializeObject(data);
            //封装有关个别HTTP请求的所有HTTP特定的信息(上下文信息)
            var content = new StringContent(value, Encoding.UTF8);
            //设置请求头的上下文类型
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            //发送Post异步请求信息
            using (var client = new HttpClient())
            {
                //发送异步请求
                var result = client.PostAsync(url, content).Result;
                //获取请求返回的结果数据并将其序列化为字符串
                var response = result.Content.ReadAsStringAsync().Result;
                if (result.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new HttpRequestException($"调用接口:{url}报错,StatusCode:{result.StatusCode},Msg:{response}");
                //将返回结果反序列化为指定Model
                return JsonConvert.DeserializeObject<ApiResult<TResult>>(response);
            }
        }

        /// <summary>
        /// 通过Get方式请求数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <returns></returns>
        public static ApiResult<T> Get<T>(string url)
        {
            //发送Get异步请求信息
            using (var client = new HttpClient())
            {
                //发送异步请求
                var result = client.GetAsync(url).Result;
                //获取请求返回的结果数据并将其序列化为字符串
                var response = result.Content.ReadAsStringAsync().Result;
                if (result.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new HttpRequestException($"调用接口:{url}报错,StatusCode:{result.StatusCode},Msg:{response}");
                //将返回结果反序列化为指定Model
                return JsonConvert.DeserializeObject<ApiResult<T>>(response);
            }
        }

        #endregion POST及GET请求方法
    }

    /// <summary>
    /// 返回结果类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ApiResult<T>
    {
        private static readonly string SUCCESS = "200";
        private static readonly string FAIL = "500";
        public string Code { get; set; }
        public string Message { get; set; }
        public T Data { get; set; }
        public int Total { get; set; }

        /// <summary>
        /// 访问成功
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static ApiResult<T> Success(T data)
        {
            return new ApiResult<T>()
            {
                Data = data,
                Code = SUCCESS
            };
        }

        /// <summary>
        /// 访问失败
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static ApiResult<T> Fail(string message)
        {
            return new ApiResult<T>()
            {
                Code = FAIL,
                Message = message
            };
        }

Interface calls

After you define a good HttpClient, we can be started by way of interface calls access to the site, and this in part because of our different environments, so the needs of different domain names, domain names so you need to read through the configuration:

 //封装url请求Model,用于填充到POST请求的body里
var urlModel = new UrlModel()
 {
    tenantId = tenantId,
    appName = appName,
    api_key = ApiKey
  };      
var url = $"{HOST}/tmlapi/tmlRequest?&tenantId={tenantId}&appName={appName}&api_key={ApiKey}";
//开启http客户端发送Post请求
var result = HttpClientHelper.ExecuteFunc<ApiResult<string>>(() => HttpClientHelper.Post<string, UrlModel>(url, urlModel));          

In this process, we design a good body of a POST request to be placed in the desired parameters and place it in a model , and then depending on the configuration and stitching good read domain name url, to be placed in the query parameters spliced to the url , HttpClient method together with the model passed along. Special attention is needed if a POST request, defined in the body to put in the request parameters in a model pass in, and is defined as a request parameter query must be spliced to upload the url , if defined as a query, and then into the body Lane will lead to a lack of request parameters does not make sense.
Here Insert Picture Description
All in all, you need to call HttpClient, be sure to package one way and then do the treatment retry mechanism, after all, is to visit the site. Also note that the transfer of formal parameters!

Published 240 original articles · won praise 114 · views 180 000 +

Guess you like

Origin blog.csdn.net/sinat_33087001/article/details/103304323