1

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();
        }
    }
}
5
  • Seems like that you a trying to access a domain that does not exist "No such host is known".. Check the host/domain-name where the error is thrown. Commented Jan 22, 2020 at 11:23
  • No such host is known -> it seems your device cannot get the IP for the host name book.sogohotel.com. I can from my PC, I would start trying with the browser from your device Commented Jan 22, 2020 at 11:24
  • book.sogohotel.com is only a dummy, I don't want to expose the real domain for security purposes. But I already try to send the request through Postman and I got the response without error. Commented Jan 22, 2020 at 11:49
  • just because Postman on your desktop can resolve it does not mean that the network stack on your device/emulator can. Try loading it using the browser on your device. Commented Jan 22, 2020 at 12:51
  • Make sure if the HTTPS service supports TLS 1.1 or 1.2, there is more info on that here learn.microsoft.com/en-us/xamarin/cross-platform/… Commented Jan 22, 2020 at 13:46

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.