我在.NET MAUI 中没有找到任何关于 HttpClient 的信息。
有谁知道这项服务:
builder.Services.AddHttpClient<IMyService, MyService>();
可以在MAUI的启动MauiProgram.cs中吗?然后将 HttpClient 注入到要使用它的地方。我已经尝试了一切,但似乎不起作用。只有 HttpClient 的 AddSingleton 对我有用,但它似乎不是最佳的。
PS.:我必须安装 nuget 包 Microsoft.Extensions.Http 才能使用 AddHttpClient 服务。
更新:
工作代码:
MauiProgram.cs
builder.Services.AddTransient<Service<Display>, DisplayService>();
builder.Services.AddTransient<Service<Video>, VideoService>();
builder.Services.AddTransient<Service<Image>, ImageService>();
builder.Services.AddTransient<Service<Log>, LogService>();
builder.Services.AddSingleton(sp => new HttpClient() { BaseAddress = new Uri("https://api.myapi.com") });
使用服务的 VideosViewModel.cs 示例
[INotifyPropertyChanged]
public partial class VideosViewModel
{
readonly Service<Video> videoService;
[ObservableProperty]
ObservableCollection<Video> videos;
[ObservableProperty]
bool isEmpty;
[ObservableProperty]
bool isRefreshing;
public VideosViewModel(Service<Video> videoService)
{
this.videoService = videoService;
}
[ICommand]
internal async Task LoadVideosAsync()
{
#if ANDROID || IOS || tvOS || Tizen
UserDialogs.Instance.ShowLoading("Henter videoer fra databasen...");
#endif
await Task.Delay(2000);
Videos = new();
try
{
await foreach (Video video in videoService.GetAllAsync().OrderBy(x => x.Id))
{
Videos.Add(video);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
IsRefreshing = false;
#if ANDROID || IOS || tvOS
UserDialogs.Instance.HideLoading();
#endif
if (Videos.Count is 0)
{
IsEmpty = true;
}
else
{
IsEmpty = false;
}
}
}
[ICommand]
async Task UploadVideoAsync()
{
await Shell.Current.DisplayAlert("Upload en video", "Under opbygning - kommer senere!", "OK");
}
}
无法运行代码:
MauiProgram.cs
builder.Services.AddHttpClient<Service<Display>, DisplayService>(sp => sp.BaseAddress = new Uri("https://api.myapi.com"));
builder.Services.AddHttpClient<Service<Video>, VideoService>(sp => sp.BaseAddress = new Uri("https://api.myapi.com"));
builder.Services.AddHttpClient<Service<Image>, ImageService>(sp => sp.BaseAddress = new Uri("https://api.myapi.com"));
builder.Services.AddHttpClient<Service<Log>, LogService>(sp => sp.BaseAddress = new Uri("https://api.myapi.com"));
VideosViewModel.cs 与上面的工作代码相同。
具体不起作用的是我在 OrderBy(x => x.Id) 上遇到对象引用异常,特别是在 ViewModel 中突出显示了 x.Id。删除 OrderBy 方法不再出现异常,但视图除了一个随机的空框架之外不显示任何数据。
请勿在 MAUI 中使用 builder.Services.AddHttpClient。 使用一个实例。
builder.Services.AddHttpClient 对我有用。这是我的设置方式:在主程序中,我添加了 .AddHttpClient()
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.Services.AddHttpClient();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
在 AppShell.xaml 中,我删除了 DataTemplate 定义,使其成为准系统:
<Shell
x:Class="MAUIMultiPage.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAUIMultiPage"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
x:Name="homepage"
Title="Home"
/>
<ShellContent
x:Name="specialOpsPage"
Title="Special Ops"
/>
</TabBar>
</Shell>
请注意,我为 ShellContents 指定了 x:Name。 DataTemplates 在 AppShell.xaml 后面的代码中定义,我可以在其中传递一个带有 IHttpClientFactory 的 Func 对象作为 DI 参数,如下所示:
public partial class AppShell : Shell
{
public AppShell(IHttpClientFactory httpClientFactory)
{
InitializeComponent();
homepage.ContentTemplate = new DataTemplate(() => new MainPage(httpClientFactory));
specialOpsPage.ContentTemplate = new DataTemplate(() => new SpecialOps(httpClientFactory));
}
}
对于App类,我们可以注入IHttpClientFactory,它被传递给AppShell:
public partial class App : Application
{
public App(IHttpClientFactory httpClientFactory)
{
InitializeComponent();
MainPage = new AppShell(httpClientFactory);
}
}
在每个单独的页面中,我都会从 PageCollection 类中获得 iHttpClientFactory
public partial class SpecialOps : ContentPage
{
private readonly IHttpClientFactory _httpClientFactory;
public SpecialOps(IHttpClientFactory httpClientFactory)
{
InitializeComponent();
this._httpClientFactory = httpClientFactory;
}
private async void Button_Clicked(object sender, EventArgs e)
{
var httpClient = _httpClientFactory.CreateClient();
var result = await httpClient.GetAsync("https://dummy.restapiexample.com/api/v1/employees");
txtResult.Text = await result.Content.ReadAsStringAsync();
}
}
此示例的完整解决方案位于我的 GitHub 存储库中:https://github.com/yogigrantz/MAUIWithHttpClientFactory