在xamarin表单中处理api请求的一个地方处理异常

问题描述 投票:0回答:1

我正在研究Xamarin表单,我需要在整个项目中发送大量的API请求。我创建了一个全局HTTP客户端对象并在每个位置使用它。当Internet关闭或找不到服务器时,如何处理HttpRequestException。我想在一个地方处理这个异常,这样我就不会在数百个地方重复代码了。我应该在哪里以及如何做。在Xamarin.Forms中,我读到我们无法全局处理异常。我想在一个地方处理所有异常,并从那里显示一个错误页面。

服务类

 public partial class Service
    {
        private string BaseUrl { get; set; }
        private string AccessToken { get; set; }
        private static HttpClient Client = new HttpClient();
        public Service()
        {
        }
        public Service(string BaseUrl)
        {
            this.BaseUrl = BaseUrl;
        }
        public Service(string BaseUrl, string AccessToken)
        {
            this.BaseUrl = BaseUrl;
            this.AccessToken = AccessToken;

        }

    }
}

Api消费方法之一

public async Task<bool> ExternalLogin(string email)
        {
            bool UserAlreadyRegistered = false;
            bool IsUserRegistered = true;
            var request = new HttpRequestMessage()
            {
                RequestUri = new Uri(this.BaseUrl + "api/Account/UserInfo"),
                Method = HttpMethod.Get,
            };
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);

            var UserInfo = await Client.SendAsync(request);
            if (UserInfo.IsSuccessStatusCode)
            {
                var response = await UserInfo.Content.ReadAsStringAsync();
                var authenticationTicket = JsonConvert.DeserializeObject<dynamic>(response);
                if (authenticationTicket.Value<bool>("HasRegistered"))
                {
                    UserAlreadyRegistered = true;
                }
            }
            if (!UserAlreadyRegistered)
            {
                request = new HttpRequestMessage()
                {
                    RequestUri = new Uri(this.BaseUrl + "api/Account/RegisterExternal"),
                    Method = HttpMethod.Post,
                };
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
                var content = new FormUrlEncodedContent(new[] {
                            new KeyValuePair<string, string> ("Email", email)
                        });
                request.Content = content;
                var authenticateResponse = await Client.SendAsync(request);
                if (!authenticateResponse.IsSuccessStatusCode)
                {
                    IsUserRegistered = false;
                }
            }
            return IsUserRegistered;
        }

在EvZ Ans之后更新

呼叫扩展方法:

string result = await Task.Run(() => new Service(Settings.BaseUrl, Settings.AccessToken).Register(Model)).ExecuteAsyncOperation();

扩展方法:

public static class TaskExtensions
    {
        public static async Task<T> ExecuteAsyncOperation<T>(this Task<T> operation)
        {
            try
            {
                return await operation;
            }
            catch
            {
                return default(T);
            }
        }
    }
c# xamarin exception-handling xamarin.forms httpclient
1个回答
1
投票

扩展您的服务以使用下一种方法(根据您的需要):

async Task<T> Post<T>(string url, object body)
async Task<T> Get<T>(string url)

这些方法中的每一种都应该得到一个HttpResponseMessage,你应该检查成功或失败。

另外,你可以引入一个MyApi类,它将使用你的Service类中的方法:

async AuthenticationResult Authenticate() =>
await service.Post("http://myapi.com/token", new AuthenticationRequest { Username = "x", Password = "xxx"});

P.S。:请注意Service是一个非常糟糕的命名。目前还不清楚Service课程的责任。 P.S.S。:或者你可以为Task创建一个扩展方法来包装所有的api请求并拥有一个try / catch。 简单的例子:

public static class TaskExtensions
{
    public static async Task<T> ExecuteAsyncOperation<T>(this Task<T> operation)
    {
        try
        {
            return await operation;
        }
        catch{ }
    }
}

var token = await apiService.Authenticate(string username, string password).ExecuteAsyncOperation();
© www.soinside.com 2019 - 2024. All rights reserved.