无法解析类型为'System.Net.Http.HttpClient'的服务

Cha*_*glu 9 c# asp.net asp.net-core

我创建了一个ViewComponent类,REST API使用调用了HttpClient,这是代码:

public class ProductsViewComponent : ViewComponent
{
    private readonly HttpClient _client;

    public ProductsViewComponent(HttpClient client)
    {
        _client = client ?? throw new ArgumentNullException(nameof(client));
    }

    public async Task<IViewComponentResult> InvokeAsync(string date)
    {
        using(var response = await _client.GetAsync($"/product/get_products/{date}"))
        {
            response.EnsureSuccessStatusCode();
            var products = await response.Content.ReadAsAsync<List<Products>>();
            return View(products);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

InvalidOperationException:尝试激活MyApp.ViewComponents.ProductsViewComponent时无法解析类型为'System.Net.Http.HttpClient'的服务

我注射HttpClientConfigureService方法提供Startup了这种方式:

 services.AddHttpClient<FixturesViewComponent>(options =>
 {
    options.BaseAddress = new Uri("http://80.350.485.118/api/v2");
 });
Run Code Online (Sandbox Code Playgroud)

更新:

我也注册了ProductsViewComponent同样的错误。

小智 16

我有一个类似的问题-问题出在双重注册中:

services.AddHttpClient<Service>();
services.AddSingleton<Service>();  // fixed by removing this line
Run Code Online (Sandbox Code Playgroud)


Kir*_*kin 10

TLDR; ViewComponents 不支持开箱即用的键入客户端。要解决此问题,请AddViewComponentsAsServices()在对 的调用末尾添加对 的调用services.AddMvc(...)


在能够重现您的问题之后进行了很长时间的聊天之后,我们最初确定所观察到的问题特定于ViewComponents。即使调用IServiceCollection.AddHttpClient<SomeViewComponent>(),将 的实例传递HttpClientSomeViewComponents 构造函数也只是拒绝工作。

但是,之间放置一个新类 ( SomeService)可以按预期工作。这就是文档所说的类型化客户端。代码看起来有点像这样: SomeComponentHttpClient

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient<SomeService>();
    // ...
}

// SomeService.cs
public class SomeService
{
    public SomeService(HttpClient httpClient)
    {
        // ...
    }
}

// SomeViewComponent.cs
public class SomeViewComponent
{
    public SomeViewComponent(SomeService someService)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我已经说过的,这种方法有效 - ASP.NET Core DI 系统非常乐意创建 的实例SomeService及其类型化HttpClient实例。

要重述原始问题,请使用以下示例代码:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient<SomeViewComponent>();
    // ...
}

public class SomeViewComponent
{
    public SomeViewComponent(HttpClient httpClient)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,ASP.NET Core DI 系统SomeViewComponent由于无法解析HttpClient. 事实证明,这不仅仅针对ViewComponents:它也适用于Controllers 和TagHelpers(感谢 Chris Pratt 对TagHelpers 的确认)。

有趣的是,以下也有效:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient<SomeViewComponent>();
    // ...
}

public class SomeViewComponent
{
    public SomeViewComponent(IHttpClientFactory httpClientFactory)
    {
        var httpClient = httpClientFactory.CreateClient("SomeViewComponent")
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我们利用了调用为我们AddHttpClient<SomeViewComponent>注册了一个命名客户端的事实。

为了能够HttpClient直接注入到 a 中ViewComponent,我们可以在向AddViewComponentsAsServicesDI 注册 MVC 时添加一个调用:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(...)
        .AddViewComponentsAsServices();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

AddControllersAsServices并且AddTagHelpersAsServices也可称为添加了同样的支持ControllerS和TagHelpers分别。

如果我们更仔细地查看文档,很明显那里的示例都没有将 aHttpClient注入Controllers et al - 根本没有提到这种方法。

不幸的是,我不知道有足够的了解ASP.NET的核心DI系统,以便能确切地解释为什么这工作方式是这样:我上面提供的信息只是解释了什么一起的解决方案。Chris Pratt 已在 Github 中打开了一个问题,以便更新文档以对此进行扩展。


Sib*_*enu 5

我在版本 2 中遇到了类似的错误。Azure Function根据本文档,我们应该能够将其添加IHttpClientFactory为依赖项。将其添加DI到我的 Azure 函数中后,我收到下面提到的错误。

Microsoft.Extensions.DependencyInjection.Abstractions:尝试激活“OServiceBus.Adapter.FetchDataFromSubscription1”时无法解析类型“System.Net.Http.IHttpClientFactory”的服务

问题是我没有重写配置函数来将其添加HttpClient为注册依赖项。因此,我刚刚在 Azure Function 的根目录中创建了一个名为的类,Statup如下所示。

使用 Microsoft.Azure.Functions.Extensions.DependencyInjection;使用 Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(ServiceBus.Adapter.Startup))]
namespace ServiceBus.Adapter {
    public class Startup: FunctionsStartup {
        public override void Configure(IFunctionsHostBuilder builder) {
            builder.Services.AddHttpClient();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加此后,我的功能开始正常工作。希望能帮助到你。