繁体   English   中英

如何在asp.net webforms中使用HttpClient

[英]How to use HttpClient in asp.net webforms

我花了很多时间研究,但还没有找到可靠的答案,所以我想开始一个新的问题。

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

技术挑战似乎围绕着 HttpClient 导致套接字耗尽的所有“你做错了”。 所以建议是使用依赖注入(假设你正在做一个 .net core web 应用程序)或静态实例(通常用于控制台应用程序)。 但是你真的会为一个 webforms 站点(在 App_Code 或 Global.asax 中)声明一个静态变量吗?

使用任何一种常见的 REST API 都很难“正确使用”,这似乎令人难以置信。

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

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

真的很简单。 忽略它实现的IDisposable接口并创建一个像ExampleApiClient这样的单点/对象,从那里你将调用它。

将您的成员声明为:

private static readonly HttpClient client = new HttpClient();

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

不过,创建新客户端是有原因的。 例如,如果您想使用不同的代理或默认标头调用多个不同的 api,请为每个 api 创建一个,但肯定不是为每个请求创建一个。

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

这里有一些代码向您展示了如何在 webforms 应用程序中使用它,假设您的目标是 .NET 框架版本 4.7.2 或更高版本,这在您的情况下是正确的。 基本思想是新建一个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 中对此进行了解释。

这将避免 Web Forms 中的端口耗尽和陈旧的 DNS 问题。

private static readonly object CachedHttpClientLockObject = new object();
public static HttpClient CachedHttpClient {
    get {
        if (HttpRuntime.Cache.Get("Acme.HttpClient") is HttpClient client) {
            return client;
        }
        lock (CachedHttpClientLockObject) {
            client = HttpRuntime.Cache.Get("Acme.HttpClient") as HttpClient;
            if (client != null) {
                return client;
            }
            client = new HttpClient();
            HttpRuntime.Cache.Insert("Acme.HttpClient", client, null, DateTime.UtcNow.AddMinutes(30), Cache.NoSlidingExpiration, CacheItemPriority.Normal, new CacheItemRemovedCallback(CachedHttpClientRemovedCallback));
        }
        return client;
    }
}

private static void CachedHttpClientRemovedCallback(string key, object val, CacheItemRemovedReason reason) {
    (val as HttpClient)?.Dispose();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM