如何在asp.net网络表单中使用HttpClient

问题描述

我花了很多时间进行研究,但仍未找到可靠的答案,所以我想提出一个新的新问题。

在基于ASP.NET Webforms的网站中使用HttpClient类的指导是什么?请注意,这不是MVC网站,也不是.NET Core。这是一个ASP.NET Webforms网站。它在最新的.NET Framework(4.8)上。

技术挑战似乎围绕着HttpClient导致套接字耗尽的所有“您做错了”。因此建议是使用依赖项注入(假设您正在执行.net核心Web应用程序)或静态实例(通常在控制台应用程序中注明)。但是,您真的会为Webforms网站(在App_Code或Global.asax中)声明一个静态变量吗?

使用任何一种常见的REST API都很难“正确”。

一个挑战是其所有方法都是异步的。但是,我认为在从Stephen Cleary阅读足够的帖子(和答案)后,这是可行的。

在这里特别关注HttpClient的主要问题是在基于Webforms的网站中的正确用法(生命周期管理,避免套接字耗尽问题以及带有“长期存在”实例的陈旧DNS问题)。

解决方法

真的很简单。忽略它实现的IDisposable接口,并在您将其命名为ExampleApiClient的地方创建一个点/对象。

将您的成员声明为:

private static readonly HttpClient client = new HttpClient();

并通过在公共函数中使用它来封装其使用。

尽管有一个创建新客户端的理由。例如,如果您要调用具有不同代理或默认标头的多个不同的api,请为每个api创建一个,但不必为每个请求创建一个。

,

避免套接字耗尽和您提到的DNS问题的方法是使用HttpClientFactory来为您管理客户端创建。 Microsoft docs中对此进行了描述。

这里有一些代码向您展示了如何在Webforms应用程序中使用它,假设您的目标是.NET Framework 4.7.2或更高版本(在您的情况下为true)。基本思想是新建一个ServiceCollection并将其配置为一个httpClientfactory。然后构建它并使用它给您和httpClientfactory。

首先安装nuget包Microsoft.Extensions.Http。然后添加对System.Net.Http的引用。

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;

namespace HttpClientExample
{
    public static class HttpClientFactoryProvider
    {
        private static IHttpClientFactory _httpClientFactory;
        private const string _ClientKey = "DotNetClientKey";

        private static IHttpClientFactory GetHttpClientFactory()
        {
            if (_httpClientFactory != null)
            {
                return _httpClientFactory;
            }
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddHttpClient(_ClientKey);
            var serviceProvider = serviceCollection.BuildServiceProvider();
            _httpClientFactory = serviceProvider.GetService<IHttpClientFactory>();
            return _httpClientFactory;
        } 

        public static HttpClient GetClient()
        {
            return GetHttpClientFactory().CreateClient(_ClientKey);
        }
    }
 
    //here's an example of how a webform can accesses the httpclient through the above code
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender,EventArgs e)
        {    
            var client = HttpClientFactoryProvider.GetClient();
            //rest of code that uses the client
        }
    }
}

这是一个简单的示例,但是您可以像在dotnet核心应用程序中一样配置事物以执行所需的操作。再次在此处Microsoft docs中对此进行了说明。