分享

在Maui Blazor中优雅的访问Http(s)

 Csharp小记 2024-04-08 发布于江苏

前言

    个人接触Maui的时间不算长,由于综合考虑了个人的技术栈以及实际需求,就采用了Maui Blazor的开发框架(主要是为了能够适配浏览器以及降低开发成本)。

可是是深受Axios的影响,所以对拦截器就情有独钟,再加上调用接口的时候本身就需要带上一些全局签名等参数,所以需要封装一个Http的服务,此处使用IHttpClientFactory来实现。







开发环境:.NET 8

开发工具:Visual Studio 2022

 









实现步骤

  1. 创建好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;});

  1. 封装一个HttpService,其分别实现了自动添加HttpHeaderPostJsonPostObject以及一个简单的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); } }
  1. 以上自定义了一个ILocalStorageService用来存储和获取Token,主要是针对到不同的平台不同的存取方式,这个具体的实现方式在后面的文章中再写。
  2. 另外为什么使用IHttpClientFactory而不是直接使用HttpClient,其一是使用依赖注入比较方便,其二是对象的释放问题。
  3. 如何使用?
//MauiProgram中注入builder.Services.AddSingleton<HttpService>();
//_Imports.razor中加入全局@inject HttpService _HttpService
//页面中调用 var res = await _HttpService.PostObject<T>(url, data);

  1. 最后就是有个问题,我不知道有没有更好的解决方案,如果有的话,还请留言相告。就是我是在请求时添加了HttpHeader,这就需要先移除再添加,我本以为直接在构造函数中添加后,其可以直接动态获取(可能是单例注入的原因,但是如果这里不使用单例,那将没有任何意义)。
 

实现效果

 
☛☛☛点击此处下载源码☚☚☚



    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多