首页 > 解决方案 > 发送 httpclient 请求时出现 SocketException

问题描述

我有一个用于 Web 服务请求的基类,我的代码之前在我的 Xamarin Android 应用程序中工作,但现在出现错误。在获得响应后,我已经 .Dispose() httpclient 以及请求函数中的 .Disponse() HttpResponseMessage 变量。

注意:“ https://book.sogohotel.com ”只是一个虚拟域,因为我不想暴露真实的 IP 或站点

我有 2 个异步方法。

public async Task GetAvailableRooms(){
 await GetToken();
 await GetRooms(Token);
}

获得令牌然后点击 GetRoom() 我得到了 Socket Exception

我尝试使用 POSTMAN 发送请求,但得到的响应没有错误。

System.Net.Sockets.SocketException(0x80004005): No such host is known
at System.Net.Http.ConnectHelper.ConnectAsync(System.String host, System.Int32 port, System.Threading.CancellationToken cancellationToken)[0x000c8] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs:65 }

有没有人遇到过这种情况,尤其是 Xamarin Mobile Developer?

这是我的基类代码:

using MyApp.Mobile.Client.APIService.Helper;
using MyApp.Mobile.Client.Common.Constants;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace MyApp.Mobile.Client.APIService.Base
{
    public class ApiServiceBase
    {
        public static string AppBaseAddress = @"https://book.sogohotel.com";

        private Uri BaseAddress = new Uri(AppBaseAddress);
        public static string AccessToken { get; set; }
        public HttpClient httpClient { get; set; }

        public ApiServiceBase()
        {
            this.httpClient = new HttpClient() { BaseAddress = BaseAddress };
            this.httpClient.Timeout = TimeSpan.FromSeconds(60);
            this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }

        /// <summary>
        /// GetRequestAsync method handles the Get Request sent to API and returns a type HttpContent.
        /// </summary>
        /// <param name="requestUri"></param>
        /// <returns>HttpContent</returns>
        public async Task<HttpContent> GetRequestAsync(string requestUri)
        {
            HttpResponseMessage requestResponse = new HttpResponseMessage();

            try
            {
                if (!string.IsNullOrEmpty(AccessToken))
                {
                    this.httpClient.DefaultRequestHeaders.Add("x-session-token", AccessToken);
                }

                requestResponse = await this.httpClient.GetAsync(requestUri);

                if (requestResponse.IsSuccessStatusCode)
                {
                    //Dev Hint: This clause statement represents that the Get action has been processed successfully.
                }
                else if (requestResponse.StatusCode == HttpStatusCode.InternalServerError)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered InternalServer Error.
                }
                else if (requestResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered Unauthorized Error.
                }

            }
            catch (TaskCanceledException)
            {
                //Dev Hint: Need to throw or log the encountered TaskCanceledException.
            }
            catch (HttpRequestException e)
            {
                throw e.InnerException;
                //Dev Hint: Need to throw or log the encountered HttpRequestException.
            }
            catch (Exception)
            {
                //Dev Hint: Need to throw or log the encountered General Exception.
            }
            var content = requestResponse?.Content;
            requestResponse.Dispose();
            httpClient.Dispose();
            return content;
        }

        public async Task<T> GetRequestWithResponseAsync<T>(string requestUri)
        {
            try
            {
                var response = await GetRequestAsync(requestUri);
                var responseContent = response.ReadAsStringAsync().Result;

                if (response == null)
                    return default(T);

                var responseResult =  JsonConvert.DeserializeObject<T>(responseContent);

                return responseResult;
            }
            catch (Exception e)
            {
                //Dev Hint: Need to throw or log the encountered General Exception.
                throw e;
            }
        }

        public async Task<IEnumerable<T>> GetRequestWithResponseListAsync<T>(string requestUri)
        {
            try
            {
                var response = await GetRequestAsync(requestUri);
                var responseContent = response.ReadAsStringAsync().Result;

                if (response == null)
                    return default(IEnumerable<T>);

                var responseResult = JsonConvert.DeserializeObject<IEnumerable<T>>(responseContent);

                return responseResult;
            }
            catch(JsonException je)
            {

                // JsonConvert.DeserializeObject error
                // Dev Hint: Need to throw or log the encountered General Exception.
                throw je;
            }
            catch (Exception e)
            {
                //Dev Hint: Need to throw or log the encountered General Exception.
                throw e;
            }
        }


        /// <summary>
        /// PostRequestAsync method handles the Post Request sent to API and returns a type HttpContent.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="requestUri"></param>
        /// <param name="content"></param>
        /// <returns>HttpContent</returns>
        public async Task<HttpContent> PostRequestAsync<T>(string requestUri, T content)
        {
            string jsonString = string.Empty;
            StringContent stringJsonContent = default(StringContent);
            HttpResponseMessage requestResponse = new HttpResponseMessage();

            try
            {
                if (!string.IsNullOrEmpty(AccessToken))
                {
                    this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
                }

                jsonString = JsonConvert.SerializeObject(content);
                stringJsonContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
                requestResponse = await this.httpClient.PostAsync(requestUri, stringJsonContent);

                if (requestResponse.IsSuccessStatusCode)
                {
                    //Dev Hint: This clause statement represents that the Get action has been processed successfully.
                }
                else if (requestResponse.StatusCode == HttpStatusCode.InternalServerError)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered InternalServer Error.
                }
                else if (requestResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered Unauthorized Error.
                }

            }
            catch (TaskCanceledException)
            {
                //Dev Hint: Need to throw or log the encountered TaskCanceledException.
            }
            catch (HttpRequestException)
            {
                //Dev Hint: Need to throw or log the encountered HttpRequestException.
            }
            catch (Exception)
            {
                //Dev Hint: Need to throw or log the encountered General Exception.
            }

            var responseContent = requestResponse?.Content;
            requestResponse.Dispose();
            httpClient.Dispose();
            return responseContent;
        }

        public async Task<string> GetSessionTokenAsync()
        {
            HttpResponseMessage requestResponse = new HttpResponseMessage();
            try
            {

                requestResponse = await this.httpClient.PostAsync(EndPoints.GetSessionToken, null);
                if (requestResponse.IsSuccessStatusCode)
                {
                    //Dev Hint: This clause statement represents that the Get action has been processed successfully.
                    var result = requestResponse.Headers.GetValues("x-session-token");
                    return result.FirstOrDefault();
                }
                else if (requestResponse.StatusCode == HttpStatusCode.InternalServerError)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered InternalServer Error.
                }
                else if (requestResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //Dev Hint: This clause statement represents that the Get action has encountered Unauthorized Error.
                }

            }
            catch (TaskCanceledException a)
            {
                //Dev Hint: Need to throw or log the encountered TaskCanceledException.
            }
            catch (HttpRequestException b)
            {
                //Dev Hint: Need to throw or log the encountered HttpRequestException.
            }
            catch (Exception c)
            {
                //Dev Hint: Need to throw or log the encountered General Exception.
            }

            return requestResponse.StatusCode.ToString();
        }
    }
}

标签: c#xamarin.forms.net-coredotnet-httpclientsocketexception

解决方案


您正在使用您的代码发出多个请求。这会导致错误和异常。您应该使您的 HttpClient 静态并重用它而不是丢弃它。您可以在本文中找到更多信息:您使用 HTTPCLIENT 错误


推荐阅读