1

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

fkucuk
  • 631
  • 1
  • 9
  • 21
  • Post any code in the question itself. The code should actually reproduce the problem It's the **server** that returns different responses, not HttpClient. BTW both links return JSON in Chrome – Panagiotis Kanavos Sep 23 '20 at 09:36
  • Check this post https://stackoverflow.com/questions/40794275/return-jpeg-image-from-asp-net-core-webapi – avikalb Sep 23 '20 at 09:37
  • @avhornet how is this relevant? According to the question in both links the server returns JSON, not an image. – Panagiotis Kanavos Sep 23 '20 at 09:37
  • @avhornet although, running this code in .NET Core returns an image ... – Panagiotis Kanavos Sep 23 '20 at 09:41
  • No repro. This code returns an image in .NET Core as well. In fact, the screenshots look like a dump of the response object, not actual JSON responses – Panagiotis Kanavos Sep 23 '20 at 09:44
  • I've corrected the links. – fkucuk Sep 23 '20 at 09:47
  • Looks like HttpResponseMessage object from `client.GetAsync(uri);` is converted to JSON object in .NET core without dealing with contents inside its. It is like returning an object. But in .NET Framework the contents of HttpResponseMessage from `client.GetAsync(uri);` is returned. This is not the issue with HttpClient but it is how the .NET frameworks are dealing with the response before returning it to the client. – Chetan Sep 23 '20 at 10:22
  • https://stackoverflow.com/questions/39177576/how-to-to-return-an-image-with-web-api-get-method/39177684 Looks like returning file from .net core web API does not work the same way as it was with .NET framework. You might want to change approach here from HttpResponseMessage to IActionResult. – Chetan Sep 23 '20 at 10:43

2 Answers2

0

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");
        }
    }
}
Chetan
  • 6,711
  • 3
  • 22
  • 32
0

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");
            }
        }
fkucuk
  • 631
  • 1
  • 9
  • 21