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

Posted

技术标签:

【中文标题】在一个地方处理 xamarin 表单中 api 请求的异常【英文标题】:Handle Exception at one place for api request in xamarin forms 【发布时间】:2018-02-25 08:16:42 【问题描述】:

我正在处理 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);
            
        
    

【问题讨论】:

【参考方案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();

【讨论】:

哪一个是最好的方法?您正在谈论的扩展方法的任何示例? 最好的方式将是最适合您的方式。用一个例子更新了我的答案。 请查看我所做的编辑。这是正确的方法吗?

以上是关于在一个地方处理 xamarin 表单中 api 请求的异常的主要内容,如果未能解决你的问题,请参考以下文章

xamarin 表单中的 Web API 请求错误

大家好,我想开发使用Xamarin表单的导航应用程序。我能用什么?

xamarin 表单中全局不支持 pushasync 的解决方案是啥?

Xamarin 表单四舍五入 SearchHandler

Xamarin 表单导航和处理登录页面

使用本机库中的功能的 Xamarin 表单应用程序