前言
个人接触Maui的时间不算长,由于综合考虑了个人的技术栈以及实际需求,就采用了Maui Blazor的开发框架(主要是为了能够适配浏览器以及降低开发成本)。
可是是深受Axios的影响,所以对拦截器就情有独钟,再加上调用接口的时候本身就需要带上一些全局签名等参数,所以需要封装一个Http的服务,此处使用IHttpClientFactory
来实现。
开发环境:.NET 8
开发工具:Visual Studio 2022
实现步骤
MauiProgram
中实现以下依赖注入,这里主要实现了三个功能,第一是超时配置,第二是接口地址配置(IP地址10.0.2.2表示模拟器中调用本地的服务,类似于在本机浏览器中使用127.0.0.1)。第三是忽略证书错误(在调试或者没有证书的情况下尤为重要,如果是android的话,还需要在AndroidManifest.xml
文件application节点上配置android:usesCleartextTraffic="true"
)。builder.Services.AddHttpClient("AppClient", (client) =>
{
client.Timeout = TimeSpan.FromSeconds(30);
client.BaseAddress = new Uri("https://10.0.2.2:7059/");
}).ConfigurePrimaryHttpMessageHandler((configure) =>
{
var handler = new HttpClientHandler();
//忽略所有证书错误
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
return handler;
});
HttpHeader
、PostJson
、PostObject
以及一个简单的Get
请求方法。代码如下:public class HttpService
{
readonly string tokenTag = "token";
readonly HttpClient _httpClient;
readonly ILocalStorageService _localStorage;
public HttpService(IHttpClientFactory httpClientFactory, ILocalStorageService localStorage)
{
_localStorage = localStorage;
_httpClient = httpClientFactory.CreateClient("AppClient");
}
public async Task AddHeaders()
{
_httpClient.DefaultRequestHeaders.Remove(tokenTag);
_httpClient.DefaultRequestHeaders.Add(tokenTag, await _localStorage.GetString("UserToken"));
}
public async Task<ApiResult<T>> PostJson<T>(string url, string json)
{
await AddHeaders();
StringContent content = new StringContent(json);
HttpResponseMessage res = await _httpClient.PostAsync(url, content);
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeJsonFormat());
ApiResult<T> apiResult = await res.Content.ReadFromJsonAsync<ApiResult<T>>();
return apiResult;
}
public async Task<ApiResult<T>> PostObject<T>(string url, object data)
{
await AddHeaders();
JsonContent content = JsonContent.Create(data);
HttpResponseMessage res = await _httpClient.PostAsync(url, content);
JsonSerializerOptions options= new JsonSerializerOptions();
options.Converters.Add(new DateTimeJsonFormat());
ApiResult <T> apiResult = await res.Content.ReadFromJsonAsync<ApiResult<T>>(options);
return apiResult;
}
public async Task<string> Get(string url)
{
await AddHeaders();
return await _httpClient.GetStringAsync(url);
}
}
ILocalStorageService
用来存储和获取Token,主要是针对到不同的平台不同的存取方式,这个具体的实现方式在后面的文章中再写。IHttpClientFactory
而不是直接使用HttpClient
,其一是使用依赖注入比较方便,其二是对象的释放问题。//MauiProgram中注入
builder.Services.AddSingleton<HttpService>();
//_Imports.razor中加入全局
@inject HttpService _HttpService
//页面中调用
var res = await _HttpService.PostObject<T>(url, data);
HttpHeader
,这就需要先移除再添加,我本以为直接在构造函数中添加后,其可以直接动态获取(可能是单例注入的原因,但是如果这里不使用单例,那将没有任何意义)。实现效果
联系客服