个人接触Maui的时间不算长,由于综合考虑了个人的技术栈以及实际需求,就采用了Maui Blazor的开发框架(主要是为了能够适配浏览器以及降低开发成本)。 可是是深受Axios的影响,所以对拦截器就情有独钟,再加上调用接口的时候本身就需要带上一些全局签名等参数,所以需要封装一个Http的服务,此处使用IHttpClientFactory 来实现。 开发环境:.NET 8 开发工具:Visual Studio 2022 - 创建好Maui Blazor项目后,在
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; });
- 封装一个HttpService,其分别实现了自动添加
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 ,这就需要先移除再添加,我本以为直接在构造函数中添加后,其可以直接动态获取(可能是单例注入的原因,但是如果这里不使用单例,那将没有任何意义)。
|