Reputation: 6531
I would like to download a image from a url and serve it via a controller. Ideally I want to stream as much as possible rather than attempting to create byte arrays etc.
The reason I'm downloading file via my controller, rather than just giving foo.ImageUrl
to the consumer is because the urls are http and I'm proxying to avoid mixed content. This actions gets called by putting the absolute url to it into html img
tags
This is what I have so far:
The problem is that the image doesn't seem to have any content. The img
tag looks blank and when I navigate to it in my browser I just see the headers and nothing tries to download?
How do I make downloading from a url and returning it as a stream to the caller work?
[HttpGet]
[AllowAnonymous]
[Route(template: "Reward/FooLogo/{fooId}/bar/{barId}", Name = "FooLogo")]
public async Task<StreamContent> FooLogo(int fooId, int barId)
{
var foo = await GetFooAsync(fooId, barId);
if (string.IsNullOrWhiteSpace(foo?.ImageUrl))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
using (var response = await WebRequest.Create(foo.ImageUrl).GetResponseAsync())
{
// todo check content type
var responseStream = response.GetResponseStream();
var content = new StreamContent(responseStream);
content.Headers.ContentType = new MediaTypeHeaderValue(response.ContentType);
content.Headers.ContentLength = response.ContentLength;
return content;
}
}
Upvotes: 2
Views: 18947
Reputation: 6531
Just removing the using
didn't seem to fix my problem. I've re-written it a bit, and this seems to have fixed my problem.
[HttpGet]
[AllowAnonymous]
[Route(template: "Reward/FooLogo/{fooId}/bar/{barId}", Name = "FooLogo")]
public async Task<HttpResponseMessage> FooLogo(int fooId, int barId)
{
var foo = await GetFooAsync(fooId, barId);
if (string.IsNullOrWhiteSpace(foo?.ImageUrl))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
using (var client = new HttpClient())
{
var res = await client.GetAsync(paymentMethod.ImageUrl);
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(await res.Content.ReadAsStreamAsync());
response.Content.Headers.ContentType = res.Content.Headers.ContentType;
return response;
}
}
Upvotes: 4