使HTTPClient PostAsync和GetAsync的弹出方法?

时间:2019-06-12 05:44:26

标签: xamarin xamarin.forms xamarin.android

我想发出一个正确的HTTPClient请求。我有一个代码,但是我总是会得到这样的异常:

  
      
  1. Java.IO.IOException:套接字已关闭
  2.   
  3. System.OperationCanceledException:操作已取消。
  4.   
  5. Java.Net.SocketException:连接重置
  6.   
  7. Java.Net.SocketException:软件导致连接中止
  8.   
  9. Java.Net.UnknownHostException:android_getaddrinfo失败:EAI_NODATA(没有与主机名关联的地址)
  10.   
  11. Java.Net.UnknownHostException:无法解析主机“ tbs.scratchit.ph”:没有与主机名关联的地址
  12.   
  13. Java.IO.IOException:isConnected失败:ETIMEDOUT(连接超时)
  14.   
  15. Java.Net.SocketException:recvfrom失败:ECONNRESET(对等方重置连接)
  16.   

我总是会遇到这类异常,错误。

我开始怀疑如何才能正确创建Post Async和GetAsync以避免将来出现这些错误?

这是我创建HTTP客户端的方法:
1.我有一个名为 Constants 的类,在那里我将声明一个新的HTTP Client,以便我的项目中只有1个HTTPClient。

public class Constants
{
    public static HttpClient client = new HttpClient();
}

2。我有一个通过JSON发送参数通过PHP API从服务器获取数据的函数。

public async void FirstTimeSyncUser(string host, string database, string contact, string ipaddress)
    {
        try
        {
            syncStatus.Text = "Checking internet connection";

            string apifile = "first-time-sync-user-api.php";

            if (CrossConnectivity.Current.IsConnected)
            {
                syncStatus.Text = "Initializing first-time user sync";

                var db = DependencyService.Get<ISQLiteDB>();
                var conn = db.GetConnection();

                var getData = conn.QueryAsync<UserTable>("SELECT * FROM tblUser WHERE ContactID = ? AND Deleted != '1'", contact);
                var resultCount = getData.Result.Count;

                var current_datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                int count = 1;

                var settings = new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    MissingMemberHandling = MissingMemberHandling.Ignore
                };

                if (resultCount == 0)
                {
                    syncStatus.Text = "Getting user data from the server";

                    var link = "http://" + ipaddress + "/" + Constants.apifolder + "/api/" + apifile;
                    string contentType = "application/json";
                    JObject json = new JObject
                    {
                        { "Host", host },
                        { "Database", database },
                        { "ContactID", contact }
                    };

                     Constants.client.DefaultRequestHeaders.ConnectionClose = true;

                    var response = await Constants.client.PostAsync(link, new StringContent(json.ToString(), Encoding.UTF8, contentType));

                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStringAsync();

                        if (!string.IsNullOrEmpty(content))
                        {
                            try
                            {
                                var dataresult = JsonConvert.DeserializeObject<List<UserData>>(content, settings);
                                var datacount = dataresult.Count;

                                for (int i = 0; i < datacount; i++)
                                {
                                    syncStatus.Text = "Syncing user " + count + " out of " + datacount;

                                    var item = dataresult[i];
                                    var userid = item.UserID;
                                    var usrpassword = item.UsrPassword;
                                    var usertypeid = item.UserTypeID;
                                    var userstatus = item.UserStatus;
                                    var lastsync = DateTime.Parse(current_datetime);
                                    var lastupdated = item.LastUpdated;
                                    var deleted = item.Deleted;

                                    var insertdata = new UserTable
                                    {
                                        UserID = userid,
                                        UsrPassword = usrpassword,
                                        ContactID = contact,
                                        UserTypeID = usertypeid,
                                        UserStatus = userstatus,
                                        LastSync = lastsync,
                                        LastUpdated = lastupdated,
                                        Deleted = deleted
                                    };

                                    await conn.InsertOrReplaceAsync(insertdata);

                                    count++;
                                }

                                synccount += "Total synced user: " + count + "\n";

                                var logType = "App Log";
                                var log = "Initialized first-time sync (<b>User</b>)  <br/>" + "App Version: <b>" + Constants.appversion + "</b><br/> Device ID: <b>" + Constants.deviceID + "</b>";
                                int logdeleted = 0;

                                Save_Logs(contact, logType, log, database, logdeleted);

                                Preferences.Set("userchangeslastcheck", current_datetime, "private_prefs");

                                FirstTimeSyncSystemSerial(host, database, contact, ipaddress);
                            }
                            catch
                            {
                                var retry = await DisplayAlert("Application Error", "Syncing failed. Failed to send the data.\n\n Error:\n\n" + content + "\n\n Do you want to retry?", "Yes", "No");

                                if (retry.Equals(true))
                                {
                                    FirstTimeSyncUser(host, database, contact, ipaddress);
                                }
                                else
                                {
                                    First_Time_OnSyncFailed();
                                }
                            }
                        }
                        else
                        {
                            Preferences.Set("userchangeslastcheck", current_datetime, "private_prefs");

                            FirstTimeSyncSystemSerial(host, database, contact, ipaddress);
                        }
                    }
                    else
                    {
                        var retry = await DisplayAlert("Application Error", "Syncing failed. Server is unreachable.\n\n Error:\n\n"+ response.StatusCode +" Do you want to retry?", "Yes", "No");

                        if (retry.Equals(true))
                        {
                            FirstTimeSyncUser(host, database, contact, ipaddress);
                        }
                        else
                        {
                            First_Time_OnSyncFailed();
                        }
                    }
                }
                else
                {
                    SyncUserClientUpdate(host, database, contact, ipaddress);
                }
            }
            else
            {
                var retry = await DisplayAlert("Application Error", "Syncing failed. Please connect to the internet to sync your data. Do you want to retry?", "Yes", "No");

                if (retry.Equals(true))
                {
                    FirstTimeSyncUser(host, database, contact, ipaddress);
                }
                else
                {
                    First_Time_OnSyncFailed();
                }
            }
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
            var retry = await DisplayAlert("Application Error", "Syncing failed. Failed to send the data.\n\n Error:\n\n" + ex.Message.ToString() + "\n\n Do you want to retry?", "Yes", "No");

            if (retry.Equals(true))
            {
                FirstTimeSyncUser(host, database, contact, ipaddress);
            }
            else
            {
                First_Time_OnSyncFailed();
            }
        }
    }

3。获取所需的数据后,它将使用另一个POSTASYNC调用执行另一个功能。在上面的代码中,当我从服务器获取用户数据时,它将执行下一个功能,即 FirstTimeSyncSystemSerial(主机,数据库,联系人,ipaddress);

我在做什么错?以及我该如何改善它以避免出现这些异常?

2 个答案:

答案 0 :(得分:0)

调试代码以找出引发异常的位置。 在该代码块周围放一个try catch。然后捕获所有预期的异常,然后尝试多次回送。

答案 1 :(得分:0)

您可以拨打通用的自定义服务电话,可以在需要时在任何地方调用

 public class RestClient : IRestClient
{
    private const string TokenHeaderKey = "Any Token Header";
    private HttpClient _httpclient = new HttpClient();

    public async Task<T> GetAsync<T>(string url, string token) where T : new()
    {
        var responseContent = await ExecuteRequest(
            async () =>
            {
                try
                {
                    AddTokenToDefaultRequestsHeader(token);
                    return await _httpclient.GetAsync(url);
                }
                finally
                {
                    ClearAuthenticationHeader();
                }
            });

        return await Deserialize<T>(responseContent);
    }

    private void AddTokenToDefaultRequestsHeader(string token)
    {
        _httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(TokenHeaderKey, token);
    }

    private void ClearAuthenticationHeader()
    {
        _httpclient.DefaultRequestHeaders.Authorization = null;
    }

    private static async Task<HttpContent> ExecuteRequest(Func<Task<HttpResponseMessage>> requestFunc)
    {
        HttpResponseMessage response = null;
        try
        {
            response = await requestFunc();
            if (!response.IsSuccessStatusCode)
            {
                var message = $"Executed HTTP request returned status code {response.StatusCode} and reason phrase {response.ReasonPhrase}";

                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new Exception(message);
                }

                throw new Exception(message);
            }

            return response.Content;
        }
        catch (Exception exception)
        {
            if (exception is HttpRequestException || exception is WebException || exception is TaskCanceledException)
            {
                throw new Exception(
                    "Could not connect to service.");
            }

            throw;
        }
    }

    private static async Task<T> Deserialize<T>(HttpContent responseContent) where T : new()
    {
        try
        {
            var responseContentString = await responseContent.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<T>(responseContentString);
        }

        catch (Exception exception)
        {
            if (exception is TaskCanceledException || exception is JsonException)
            {
                throw new Exception("Could not deserialize response content.", exception);
            }
            throw;
        }
    }

并添加一个应用设置类

 public class AppSettings : IAppSettings
{
    public string Server => "server url";
    public string ServerEndPoint => "End point";

    public string Token => "Token If you Have any";
}

然后像这样呼叫

 public class Servicecall 
{
    private readonly IRestClient _restClient;
    private readonly IAppSettings _appSettings;

    public PatientService(IRestClient restClient, IAppSettings appSettings)
    {
        _restClient = restClient;
        _appSettings = appSettings;
    }

    public async Task<IList<PatientViewModel>> GetPatients()
    {
        var url = _appSettings.Server + _appSettings.EndPoint ;
        var token = _appSettings.Token;
        return GetPatientList(await _restClient.GetAsync<List<ListModelClass>>(url, token));
    }

    public IList<Model> GetPatientList(IList<ListModelClass> List)
    {
        return List.Select(p => new Model(p)).ToList();
    }
}

这样,您无需键入很多重复代码即可调用不同的服务 这样,您可以真正轻松地致电服务