首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于寄存器作用域的HttpClient在.NET核2中的应用

基于寄存器作用域的HttpClient在.NET核2中的应用
EN

Stack Overflow用户
提问于 2018-03-05 22:45:11
回答 2查看 8.4K关注 0票数 5

我有NetCore2WebAPI应用程序。在此过程中,我必须调用客户端A的API来获取一些数据。所以我使用HttpClient来调用它。客户端A还要求我在标头中传递用户in和密码。

因此,我没有直接注入HttpClient,而是对HttpClient进行包装,如下所示

代码语言:javascript
复制
public class ClientA : IClientA
{
    private readonly HttpClient _httpClient;

    public ClientA(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetData()
    {
        return await _httpClient.HttpGetAsync("someurl");
    }
 }

然后在服务中使用ClientA

代码语言:javascript
复制
  public class MyService :IMyService
  {
      private readonly IClientA _clientA

      public MyService(IClientA clientA)
      {
           _clientA= clientA
      }

      public void DoSomethig()
      {
          _clientA.GetData();
      }           
  }

然后我将在Startup.cs中注册所有内容

代码语言:javascript
复制
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IMyService, MyService>();           

        services.AddScoped(factory =>
        {
            Func<Task<IClientA>> provider = async () =>
            {
                using (var dbContext = factory.GetService<MyDBContext>())
                {
                    // get userid and password from database here

                    var httpClient = new HttpClient();
                    httpClient.DefaultRequestHeaders.Add("UserId",userid);
                    httpClient.DefaultRequestHeaders.Add("Password",password);
                    return new ClientA(httpClient);
                }
            };

            return provider;
        });
    }

不管怎么说我都错了

System.InvalidOperationException:当试图激活'XXXXXXXXX.ClientA‘时,无法解析“System.Net.Http.HttpClient”类型的服务。在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType,Type implementationType,ISet1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet1 callSiteChain)

为简洁起见删除剩余异常

注意,在注册期间,我是HttpClient的newing-up实例,并将它传递给ClientA类,因为我必须设置userid和密码。

为了消除上述错误,我可以向HttpClient注册UserID,并在DI框架中注册密码,我猜这是可行的。

但是,在这种情况下,如果有另一个接受ClientB的客户端HttpClient,那么DI框架将注入具有用户in和密码的同一个httpclient。这将造成安全问题,因为ClientB将在请求头中看到ClientA的凭据。

代码语言:javascript
复制
   public class ClientB(HttpClient client)
   {
        private readonly _httpClient;
        public class ClientB(HttpClient client)
        {
           _httpClient = client;
        }

        public string CallClientB(string url)
        {
            // here ClientB will receive ClientA's credentials
            return await _httpClient.HttpGetAsync(url);
        }
   }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-05 23:42:58

解决了我的问题

代码语言:javascript
复制
   services.AddScoped<IClientA>(factory =>
    {            
            var dbContext = factory.GetService<MyDBContext>();                
                // get userid and password from database here

                var httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Add("UserId",userid);
                httpClient.DefaultRequestHeaders.Add("Password",password);
                return new ClientA(httpClient);
    });
票数 -5
EN

Stack Overflow用户

发布于 2018-03-06 00:07:16

您不希望在一个限定作用域的上下文中实例化httpclient,即创建每个请求的httpclient实例,这不是该类的推荐使用模式。(不能很好地扩展)。https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

为每个客户创建一个单独的接口(假设有少量的客户)--可能在其实现中有一个代码访问安全需求,这取决于您的设置(启用了身份模拟?)

这将是( a)扩展,b)每个应用程序实例/启动时每个客户只运行一次,以及( c)强制对使用情况进行访问检查。

而且,这个答案是连接的,并与您的头需求相关- HttpClient single instance with different authentication headers

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49120741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档