简体   繁体   中英

Sytem.Net.Http.HttpClient acts different in .net core and .net framework

I have a 4.7.2 application and I'm trying to rewrite it in .net core 3.1.

I have a method in a controller below. Of course, the real code is different I receive some parameters and generate a URL, etc. But the idea is the same. I am trying to reflect another server's response.

    [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);
        }
    }

But interestingly, .net framework and core act totally different.

Framework, returns the image as I expected ( .net Framework 4.7.2 Sample ).

But core returns a json in the body ( .net Core 3.1 Sample ).

I've checked the Microsoft Documentation, they are the same for Sytem.Net.Http.HttpClient class both in netCore 3.1 and .net Framework 4.7.2.

To reproduce you can create a fresh netCore and .netFramework apps. BTW I've created a repo for this projects: https://github.com/fkucuk/imagereflectorhttpclient

Looks like treatment of HttpResponseMessage returned from client.GetAsync is different between .NET Framework and .NET Core framework.

While .NET Framework either returns the HttpResponseMessage as it is to the API client or retrieves the contents and wraps it into another HttpResponseMessage before returning it to the client, .NET Core considers it as an object and uses default media converter (JSON here) to transform it and wraps it again to another HttpResponseMessage and returns to the client of your API.

Also with the latest development in .NET Core, HttpResponseMessage is less likely used for Web API. You can use IActionResult which can be use to return pretty much any kind of response from the API.

You can read more about it here

To solve your problem, following is my recommendation.

[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");
        }
    }
}

Thanks Chetan, The solution you provided does not return the file itself I guess.

I've came up with the following solution.

But I'm not sure if this will cause a leak. I'm not disposing the stream.

        [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");
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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