首页 > 解决方案 > HttpClient - 最佳实践解决方法

问题描述

我确实了解HttpClient 被设计为可重复用于多次调用,并且我已经对为什么创建单个静态实例或为 HttpClient 使用 Singleton 是理想的,因为在处理后 TCP 套接字有可能由于 TCP 连接生命周期而保持打开状态。

下面是我为我的中央库创建的一个单例类,以便保留和重用HttpClient. 有人可以帮我将其转换为使用IHttpClientFactory吗?

public class HttpFunctions
{
    #region Class Members
    private HttpClientHandler Http_Client_Handler { get; set; }
    private HttpClient Http_Client { get; set; }
    #endregion


    #region Constructor
    public HttpFunctions()
    {
        InitHttpClient();
    }

    ~HttpFunctions()
    {
        Dispose();
    }
    #endregion


    #region Methods
    #region Post
    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        T1 response = new T1();

        try
        {
            Http_Client.DefaultRequestHeaders.Clear();

            if (authenticationToken != null)
                Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;

            if (httpHeaders != null)
            {
                foreach (Tuple<string, string> httpHeader in httpHeaders)
                    Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
            }

            if (cookies != null)
            {
                foreach (Cookie cookie in cookies)
                    Http_Client_Handler.CookieContainer.Add(requestUri, cookie);
            }

            string jsonPayload = JsonConvert.SerializeObject(payload);
            using (HttpContent httpContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json"))
            {
                string failedReason = string.Empty;
                bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
                {
                    bool success = false;

                    using (HttpResponseMessage httpResponse = Http_Client.PostAsync(requestUri, httpContent).Result)
                    {
                        if (httpResponse.IsSuccessStatusCode)
                        {
                            response = parseResponseMethod(httpResponse);
                            success = true;
                        }
                        else
                        {
                            failedReason = httpResponse.ReasonPhrase;
                            success = false;
                        }
                    }

                    return success;
                }, maxRetries, exponentialRetries, baseValue);

                if (!succeeded)
                    throw new Exception(failedReason);
            }
        }
        finally
        {
            if (cookies != null)
            {
                foreach (Cookie cookie in cookies)
                    Http_Client_Handler.CookieContainer.GetCookies(requestUri)
                                                        .Cast<Cookie>()
                                                        .ToList()
                                                        .ForEach(c => c.Expired = true);
            }
            Http_Client.DefaultRequestHeaders.Clear();
        }

        return response;
    }
    #endregion


    #region Get
    public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        T1 response = new T1();
        try
        {
            Http_Client.DefaultRequestHeaders.Clear();

            if (authenticationToken != null)
                Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;

            if (httpHeaders != null)
            {
                foreach (Tuple<string, string> httpHeader in httpHeaders)
                    Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
            }

            string failedReason = string.Empty;
            bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
            {
                bool success = false;

                using (HttpResponseMessage httpResponse = Http_Client.GetAsync(requestUri).Result)
                {
                    if (httpResponse.IsSuccessStatusCode)
                    {
                        response = parseResponseMethod(httpResponse);
                        success = true;
                    }
                    else
                    {
                        failedReason = httpResponse.ReasonPhrase;
                        success = false;
                    }
                }

                return success;
            }, maxRetries, exponentialRetries, baseValue);

            if (!succeeded)
                throw new Exception(failedReason);
        }
        finally { Http_Client.DefaultRequestHeaders.Clear(); }

        return response;
    }
    #endregion


    #region Parse
    public T1 ParseToResponseContract<T1>(HttpResponseMessage httpResponse) where T1 : new()
    {
        T1 results = new T1();

        try
        {
            if (httpResponse.Content.Headers.ContentType.ToString().ToLower().Contains("application/json"))
            {
                string jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;

                using (MemoryStream jsonStreamResponse = new MemoryStream(Encoding.ASCII.GetBytes(jsonResponse)))
                {
                    //DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings()
                    //{
                    //    //DateTimeFormat = new DateTimeFormat("yyyy-MM-ddTHH:mm:ss"),
                    //    UseSimpleDictionaryFormat = true,
                    //    EmitTypeInformation = EmitTypeInformation.Never
                    //};

                    DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(T1));
                    results = (T1)dcs.ReadObject(jsonStreamResponse);
                }
            }
        }
        finally { }

        return results;
    }
    #endregion
    #endregion


    #region Private Methods
    private void InitHttpClient()
    {
        if (Http_Client == null)
        {
            Http_Client_Handler = new HttpClientHandler() { CookieContainer = new CookieContainer() };

            Http_Client = new HttpClient(Http_Client_Handler);

            Http_Client.DefaultRequestHeaders.Accept.Clear();
        }
    }

    private void Dispose()
    {
        if (Http_Client != null)
        {
            Http_Client.Dispose();

            Http_Client = null;
        }

        if (Http_Client_Handler != null)
        {
            Http_Client_Handler.Dispose();

            Http_Client_Handler = null;
        }
    }
    #endregion


    #region Static Properties
    private static readonly IHttpFunctions mHttpFunctions = new HttpFunctions();

    public static IHttpFunctions InnerFunctions
    {
        get { return mHttpFunctions; }
    }
    #endregion
}

标签: c#httpclient

解决方案


我想我最终要做的是在我的中央库项目中使用一个单例类,并且只托管一个HttpClient(非静态)实例,这样每个使用这个库的项目都会有一个单独的这个属性的单个实例。我还将实现一个 Destroyer,以便在调用项目终止后立即正确处理属性实例。

然而,这并不能解决我的问题,因为必须使用 anHttpClientHandler以便能够将 Cookie 与我的 Post 请求一起传递。在这方面需要更多的思考。

如果您认为有更好的方法或认为这种方法会导致问题,我将不胜感激。

再次感谢 :)


下面是我为中央库创建的单例类。你能帮我把它改成使用IHttpClientFactory吗?对于过度杀伤的重载方法,请提前道歉。

public class HttpFunctions
{
    #region Class Members
    private HttpClientHandler Http_Client_Handler { get; set; }
    private HttpClient Http_Client { get; set; }
    #endregion


    #region Constructor
    public HttpFunctions()
    {
        InitHttpClient();
    }

    ~HttpFunctions()
    {
        Dispose();
    }
    #endregion


    #region Methods
    #region Post
    public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, null, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(accessToken, payload, requestUri, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(ParseToResponseContract<T1>, accessToken, payload, requestUri, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
    }


    public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, null, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequestUsingBearerAuthentication<T1, T2>(parseResponseMethod, accessToken, payload, requestUri, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequestUsingBearerAuthentication<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, T2 payload, string requestUri, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        AuthenticationHeaderValue authToken = null;

        if (!string.IsNullOrEmpty(accessToken))
            authToken = new AuthenticationHeaderValue("Bearer", accessToken);

        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
    }
   

    public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(ParseToResponseContract<T1>, payload, requestUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
    }


    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        Uri absoluteUri = new Uri(requestUri, UriKind.Absolute);

        return PostRequest<T1, T2>(parseResponseMethod, payload, absoluteUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
    }



    public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
    }
    
    public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(ParseToResponseContract<T1>, payload, requestUri, authenticationToken, httpHeaders, cookies, maxRetries, exponentialRetries, baseValue);
    }


    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, httpHeaders, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return PostRequest<T1, T2>(parseResponseMethod, payload, requestUri, authenticationToken, null, cookies, maxRetries, exponentialRetries, baseValue);
    }

    public T1 PostRequest<T1, T2>(Func<HttpResponseMessage, T1> parseResponseMethod, T2 payload, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, Cookie[] cookies = null, short maxRetries = 5, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        T1 response = new T1();

        try
        {
            Http_Client.DefaultRequestHeaders.Clear();

            if (authenticationToken != null)
                Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;

            if (httpHeaders != null)
            {
                foreach (Tuple<string, string> httpHeader in httpHeaders)
                    Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
            }

            if (cookies != null)
            {
                foreach (Cookie cookie in cookies)
                    Http_Client_Handler.CookieContainer.Add(requestUri, cookie);
            }

            string jsonPayload = JsonConvert.SerializeObject(payload);
            using (HttpContent httpContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json"))
            {
                string failedReason = string.Empty;
                bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
                {
                    bool success = false;

                    using (HttpResponseMessage httpResponse = Http_Client.PostAsync(requestUri, httpContent).Result)
                    {
                        if (httpResponse.IsSuccessStatusCode)
                        {
                            response = parseResponseMethod(httpResponse);
                            success = true;
                        }
                        else
                        {
                            failedReason = httpResponse.ReasonPhrase;
                            success = false;
                        }
                    }

                    return success;
                }, maxRetries, exponentialRetries, baseValue);

                if (!succeeded)
                    throw new Exception(failedReason);
            }
        }
        finally
        {
            if (cookies != null)
            {
                foreach (Cookie cookie in cookies)
                    Http_Client_Handler.CookieContainer.GetCookies(requestUri)
                                                        .Cast<Cookie>()
                                                        .ToList()
                                                        .ForEach(c => c.Expired = true);
            }
            Http_Client.DefaultRequestHeaders.Clear();
        }

        return response;
    }
    #endregion


    #region Get
    public T1 GetRequestUsingBearerAuthentication<T1>(string accessToken, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequestUsingBearerAuthentication<T1>(accessToken, requestUri, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequestUsingBearerAuthentication<T1>(string accessToken, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequestUsingBearerAuthentication<T1>(ParseToResponseContract<T1>, accessToken, requestUri, httpHeaders, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequestUsingBearerAuthentication<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, string requestUri, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequestUsingBearerAuthentication<T1>(parseResponseMethod, accessToken, requestUri, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequestUsingBearerAuthentication<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string accessToken, string requestUri, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        AuthenticationHeaderValue authToken = null;

        if (!string.IsNullOrEmpty(accessToken))
            authToken = new AuthenticationHeaderValue("Bearer", accessToken);

        return GetRequest<T1>(parseResponseMethod, requestUri, authToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
    }



    public T1 GetRequest<T1>(string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequest<T1>(string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(ParseToResponseContract<T1>, requestUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(parseResponseMethod, requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, string requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        Uri absoluteUri = new Uri(requestUri, UriKind.Absolute);

        return GetRequest<T1>(parseResponseMethod, absoluteUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
    }


    public T1 GetRequest<T1>(Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
    }
    
    public T1 GetRequest<T1>(Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(ParseToResponseContract<T1>, requestUri, authenticationToken, httpHeaders, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        return GetRequest<T1>(parseResponseMethod, requestUri, authenticationToken, null, maxRetries, exponentialRetries, baseValue);
    }

    public T1 GetRequest<T1>(Func<HttpResponseMessage, T1> parseResponseMethod, Uri requestUri, AuthenticationHeaderValue authenticationToken = null, Tuple<string, string>[] httpHeaders = null, short maxRetries = 0, bool exponentialRetries = false, double baseValue = 2) where T1 : new()
    {
        T1 response = new T1();
        try
        {
            Http_Client.DefaultRequestHeaders.Clear();

            if (authenticationToken != null)
                Http_Client.DefaultRequestHeaders.Authorization = authenticationToken;

            if (httpHeaders != null)
            {
                foreach (Tuple<string, string> httpHeader in httpHeaders)
                    Http_Client.DefaultRequestHeaders.Add(httpHeader.Item1, httpHeader.Item2);
            }

            string failedReason = string.Empty;
            bool succeeded = ProcessFunctions.InnerFunctions.PerformUsingRetriesIf_ReturnIsFalse(() =>
            {
                bool success = false;

                using (HttpResponseMessage httpResponse = Http_Client.GetAsync(requestUri).Result)
                {
                    if (httpResponse.IsSuccessStatusCode)
                    {
                        response = parseResponseMethod(httpResponse);
                        success = true;
                    }
                    else
                    {
                        failedReason = httpResponse.ReasonPhrase;
                        success = false;
                    }
                }

                return success;
            }, maxRetries, exponentialRetries, baseValue);

            if (!succeeded)
                throw new Exception(failedReason);
        }
        finally { Http_Client.DefaultRequestHeaders.Clear(); }

        return response;
    }
    #endregion


    #region Parse
    public T1 ParseToResponseContract<T1>(HttpResponseMessage httpResponse) where T1 : new()
    {
        T1 results = new T1();

        try
        {
            if (httpResponse.Content.Headers.ContentType.ToString().ToLower().Contains("application/json"))
            {
                string jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;

                using (MemoryStream jsonStreamResponse = new MemoryStream(Encoding.ASCII.GetBytes(jsonResponse)))
                {
                    //DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings()
                    //{
                    //    //DateTimeFormat = new DateTimeFormat("yyyy-MM-ddTHH:mm:ss"),
                    //    UseSimpleDictionaryFormat = true,
                    //    EmitTypeInformation = EmitTypeInformation.Never
                    //};

                    DataContractJsonSerializer dcs = new DataContractJsonSerializer(typeof(T1));
                    results = (T1)dcs.ReadObject(jsonStreamResponse);
                }
            }
        }
        finally { }

        return results;
    }
    #endregion
    #endregion


    #region Private Methods
    private void InitHttpClient()
    {
        if (Http_Client == null)
        {
            Http_Client_Handler = new HttpClientHandler() { CookieContainer = new CookieContainer() };

            Http_Client = new HttpClient(Http_Client_Handler);

            Http_Client.DefaultRequestHeaders.Accept.Clear();
        }
    }

    private void Dispose()
    {
        if (Http_Client != null)
        {
            Http_Client.Dispose();

            Http_Client = null;
        }

        if (Http_Client_Handler != null)
        {
            Http_Client_Handler.Dispose();

            Http_Client_Handler = null;
        }
    }
    #endregion


    #region Static Properties
    private static readonly IHttpFunctions mHttpFunctions = new HttpFunctions();

    public static IHttpFunctions InnerFunctions
    {
        get { return mHttpFunctions; }
    }
    #endregion
}


推荐阅读