Nathan
Nathan

Reputation: 6531

Download and return a file from asp.net webapi

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

Answers (1)

Nathan
Nathan

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

Related Questions