Getting SocketException when sending httpclient request

0

I have a Base class for Webservice request, my code is working before in my Xamarin Android Application but now I got an error. I already .Dispose() the httpclient after getting the response and also .Disponse() the HttpResponseMessage Variable inside my request function.

NOTE: "https://book.sogohotel.com" is only a dummy domain because I don't want to expose the real IP or Site

I have 2 Async Method.

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

After getting the token then hitting the GetRoom() I got the Socket Exception

I try to sent requests using POSTMAN but I get the response without ERROR.

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 }

Does anyone encounter this before especially Xamarin Mobile Developer?

Heres my Base class code:

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-core
dotnet-httpclient
socketexception
asked on Stack Overflow Jan 22, 2020 by ralphralph • edited Jan 22, 2020 by ralphralph

1 Answer

-1

You are making multiple request with your code. That leads to errors and exceptions. You should make your HttpClient static and reuse it instead of disposing it. More information you can find in this article: YOU'RE USING HTTPCLIENT WRONG

answered on Stack Overflow Jan 22, 2020 by Adlorem

User contributions licensed under CC BY-SA 3.0