HttpClient 如何在一个地方捕获每个响应
HttpClient How to catch every response in one place
我正在开发 Xamarin.Forms 与 Web Api 2 Api 连接的应用程序,所有请求和响应都与 HttClient 一起工作。这是我的代码:
class 对于我的所有请求和 HttpClient 的定义
public class DataStore : IDataStore<object>
{
HttpClient client;
public DataStore()
{
client = new HttpClient()
{
BaseAddress = new Uri($"{App.Uri}")
};
}
我的请求之一的示例:
public async Task<User> GetProfileSetup()
{
try
{
if (CrossConnectivity.Current.IsConnected)
{
string token = DependencyService.Get<ISharedFunctions>().GetAccessToken();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(@"api/User/GetProfilSetup");
if (response.IsSuccessStatusCode)
{
string jsonMessage;
using (Stream responseStream = await response.Content.ReadAsStreamAsync())
{
jsonMessage = new StreamReader(responseStream).ReadToEnd();
}
User user = JsonConvert.DeserializeObject<User>(jsonMessage);
return user;
}
else
{
var m = response.Content.ToString();
return null;
}
}
else
{
return null;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
string error = ex.Message;
return null;
}
}
我的想法是在一个地方检查每个响应(响应状态代码)。我需要这个来抛出警报错误,刷新令牌等。有没有办法做到这一点?我想控制每个 request/response.
这与xamarin无关,是OOP中的抽象问题。您可以而且应该抽象 HttpClient 及其方法以删除所有样板文件。
示例 - GetAsync<T>(url)
将检查连接,表单请求添加必要的 headers,等待响应,检查响应状态,读取响应,最后 returns 反序列化响应。这样,如果你想添加缓存层就更容易了。基本面向对象编程。
正在抽象您的代码:
public async Task<T> GetAsync(string url)
{
try
{
if (!CrossConnectivity.Current.IsConnected)
{
// throw custom exception?
new NoNetworkException();
}
var token = DependencyService.Get<ISharedFunctions>().GetAccessToken();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
// read response and throw for logging?
new InvaidResponseException();// custom exceptions makes it easier for catching
}
using (Stream responseStream = await response.Content.ReadAsStreamAsync())
{
// there should be an async overload to read too
var jsonMessage = new StreamReader(responseStream).ReadToEnd();
return JsonConvert.DeserializeObject<T>(jsonMessage);
}
}
catch(NoNetworkException ex)
{
// handle
}
catch(InvaidResponseException ex)
{
// handle
}
}
如果有人对此有疑问,只需要实现自定义处理程序,它将继承 DelegatingHandler 的形式。我的代码示例:
public class StatusCodeHandler : DelegatingHandler
{
public StatusCodeHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
public GetStatusCode GetStatusCode = new GetStatusCode();
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
response = await base.SendAsync(request, cancellationToken);
if (response.IsSuccessStatusCode)
{
return response;
}
else
{
var status_code = (int)response.StatusCode;
GetStatusCode.GetResponseCode(status_code);
}
return response;
}
}
我正在开发 Xamarin.Forms 与 Web Api 2 Api 连接的应用程序,所有请求和响应都与 HttClient 一起工作。这是我的代码:
class 对于我的所有请求和 HttpClient 的定义
public class DataStore : IDataStore<object>
{
HttpClient client;
public DataStore()
{
client = new HttpClient()
{
BaseAddress = new Uri($"{App.Uri}")
};
}
我的请求之一的示例:
public async Task<User> GetProfileSetup()
{
try
{
if (CrossConnectivity.Current.IsConnected)
{
string token = DependencyService.Get<ISharedFunctions>().GetAccessToken();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(@"api/User/GetProfilSetup");
if (response.IsSuccessStatusCode)
{
string jsonMessage;
using (Stream responseStream = await response.Content.ReadAsStreamAsync())
{
jsonMessage = new StreamReader(responseStream).ReadToEnd();
}
User user = JsonConvert.DeserializeObject<User>(jsonMessage);
return user;
}
else
{
var m = response.Content.ToString();
return null;
}
}
else
{
return null;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
string error = ex.Message;
return null;
}
}
我的想法是在一个地方检查每个响应(响应状态代码)。我需要这个来抛出警报错误,刷新令牌等。有没有办法做到这一点?我想控制每个 request/response.
这与xamarin无关,是OOP中的抽象问题。您可以而且应该抽象 HttpClient 及其方法以删除所有样板文件。
示例 - GetAsync<T>(url)
将检查连接,表单请求添加必要的 headers,等待响应,检查响应状态,读取响应,最后 returns 反序列化响应。这样,如果你想添加缓存层就更容易了。基本面向对象编程。
正在抽象您的代码:
public async Task<T> GetAsync(string url)
{
try
{
if (!CrossConnectivity.Current.IsConnected)
{
// throw custom exception?
new NoNetworkException();
}
var token = DependencyService.Get<ISharedFunctions>().GetAccessToken();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
// read response and throw for logging?
new InvaidResponseException();// custom exceptions makes it easier for catching
}
using (Stream responseStream = await response.Content.ReadAsStreamAsync())
{
// there should be an async overload to read too
var jsonMessage = new StreamReader(responseStream).ReadToEnd();
return JsonConvert.DeserializeObject<T>(jsonMessage);
}
}
catch(NoNetworkException ex)
{
// handle
}
catch(InvaidResponseException ex)
{
// handle
}
}
如果有人对此有疑问,只需要实现自定义处理程序,它将继承 DelegatingHandler 的形式。我的代码示例:
public class StatusCodeHandler : DelegatingHandler
{
public StatusCodeHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
public GetStatusCode GetStatusCode = new GetStatusCode();
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
response = await base.SendAsync(request, cancellationToken);
if (response.IsSuccessStatusCode)
{
return response;
}
else
{
var status_code = (int)response.StatusCode;
GetStatusCode.GetResponseCode(status_code);
}
return response;
}
}