System.Net.Http.HttpClient 在 .net 核心和 .net 框架中的行为不同

Posted

技术标签:

【中文标题】System.Net.Http.HttpClient 在 .net 核心和 .net 框架中的行为不同【英文标题】:Sytem.Net.Http.HttpClient acts different in .net core and .net framework 【发布时间】:2021-01-09 11:33:50 【问题描述】:

我有一个 4.7.2 应用程序,我正在尝试在 .net core 3.1 中重写它。

我在下面的控制器中有一个方法。当然,真正的代码是不同的,我接收一些参数,生成一个URL等等。但是思路是一样的。我正在尝试反映另一台服务器的响应。

    [Route("images")]
    public async Task<HttpResponseMessage> GetImage()
    
        Uri uri = new Uri("https://img-lcwaikiki.mncdn.com/mnresize/1024/-/pim/productimages/20202/4353414/l_20202-0w9011z8-hrz_a.jpg", UriKind.Absolute);
        using (HttpClient client = new HttpClient())
        
            return await client.GetAsync(uri);
        
    

但有趣的是,.net 框架和核心的行为完全不同。

框架,按预期返回图像 (.net Framework 4.7.2 Sample)。

但核心在正文中返回一个 json (.net Core 3.1 Sample)。

我查看了 Microsoft 文档,它们对于 netCore 3.1 和 .net Framework 4.7.2 中的 Sytem.Net.Http.HttpClient 类都是相同的。

要重现,您可以创建全新的 netCore 和 .netFramework 应用程序。顺便说一句,我为这个项目创建了一个 repo: https://github.com/fkucuk/imagereflectorhttpclient

【问题讨论】:

在问题本身中发布任何代码。代码实际上应该重现问题它是返回不同响应的服务器,而不是HttpClient。顺便说一句,两个链接都在 Chrome 中返回 JSON 查看这个帖子***.com/questions/40794275/… @avhornet 这有什么关系?根据两个链接中的问题,服务器返回 JSON,而不是图像。 @avhornet 虽然,在 .NET Core 中运行此代码会返回一个图像 ... 无复制。此代码也返回 .NET Core 中的图像。实际上,屏幕截图看起来像是响应对象的转储,而不是实际的 JSON 响应 【参考方案1】:

看起来 .NET Framework 和 .NET Core 框架对从 client.GetAsync 返回的 HttpResponseMessage 的处理方式不同。

虽然 .NET Framework 要么将 HttpResponseMessage 原样返回给 API 客户端,要么检索内容并将其包装到另一个 HttpResponseMessage 中,然后再将其返回给客户端,但 .NET Core 将其视为一个对象并使用默认媒体转换器(JSON此处)对其进行转换并再次包装到另一个 HttpResponseMessage 并返回到您的 API 的客户端。

同样随着 .NET Core 的最新发展,HttpResponseMessage 不太可能用于 Web API。您可以使用IActionResult,它可用于从 API 返回几乎任何类型的响应。

您可以阅读更多关于它的信息here

为了解决您的问题,以下是我的建议。

[HttpGet]
public async  Task<IActionResult> Get()

    Uri uri = new Uri("https://img-lcwaikiki.mncdn.com/mnresize/1024/-/pim/productimages/20202/4353414/l_20202-0w9011z8-hrz_a.jpg", UriKind.Absolute);
    using (HttpClient client = new HttpClient())
    
        using (var stream = await client.GetStreamAsync(uri))
        
            return File(stream, "image/jpeg");
        
    

【讨论】:

【参考方案2】:

感谢切坦, 我猜您提供的解决方案不会返回文件本身。

我想出了以下解决方案。

但我不确定这是否会导致泄漏。我不会处理流。

        [HttpGet]
        [Route("v1")]
        public async Task<IActionResult> GetImage1()
        
            Uri uri = new Uri("https://img-lcwaikiki.mncdn.com/mnresize/1024/-/pim/productimages/20202/4353414/l_20202-0w9011z8-hrz_a.jpg", UriKind.Absolute);
            using (HttpClient client = new HttpClient())
            
                var response = await client.GetAsync(uri);
                var stream = await response.Content.ReadAsStreamAsync();
                return File(stream, "image/jpeg");
            
        

【讨论】:

以上是关于System.Net.Http.HttpClient 在 .net 核心和 .net 框架中的行为不同的主要内容,如果未能解决你的问题,请参考以下文章