3

I am currently doing a GET to a Web Api method and am passing the file name as parameter. When I get to the method, my parameters are resolved properly, and the file content is writing to the response content in the HttpResponseMessage object.

    public HttpResponseMessage Get ([FromUri]string filen)
    {
        string downloadPath = WebConfigurationManager.AppSettings["DownloadLocation"];

        var fileName = string.Format("{0}{1}", downloadPath, filen);
        var response = Request.CreateResponse();

        if (!File.Exists(fileName))
        {
            response.StatusCode = HttpStatusCode.NotFound;
            response.ReasonPhrase = string.Format("The file [{0}] does not exist.", filen);

            throw new HttpResponseException(response);
        }

        response.Content = new PushStreamContent(async (outputStream, httpContent, transportContext) =>
        {
            try
            {
                var buffer = new byte[65536];

                using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read))
                {
                    var length = (int)file.Length;
                    var bytesRead = 1;

                    while (length > 0 && bytesRead > 0)
                    {
                        bytesRead = file.Read(buffer, 0, Math.Min(length, buffer.Length));
                        await outputStream.WriteAsync(buffer, 0, bytesRead);
                        length -= bytesRead;
                    }
                }

            }
            finally
            {
                outputStream.Close();
            }

        });

        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = filen
        };

        return response;
    }

Instead of seeing the file being downloaded, nothing seems to happen. It seems the file just get lost anywhere. I would like to have the browser to auto download the file. I do see the content in the response in fiddler. So what happened? Any pointers would be appreciated!

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/octet-stream
Expires: -1
Server: Microsoft-IIS/8.0
Content-Disposition: attachment; filename=w-brand.png
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcSnVubGlcQXN5bmNGaWxlVXBsb2FkV2ViQVBJRGVtb1xBc3luY0ZpbGVVcGxvYWRXZWJBUElEZW1vXGFwaVxGaWxlRG93bmxvYWQ=?=
X-Powered-By: ASP.NET
Date: Thu, 12 Feb 2015 19:32:33 GMT
27b5
PNG
...
junli antolovich
  • 323
  • 5
  • 17

2 Answers2

1

I am not sure, but you can try with this code, it worked for me:

result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "SampleImg"; 

Maybe it is a problem related with your PushStreamContent.

In the next link you can see how to consume that from a javascript client: How to download memory stream object via angularJS and webaAPI2

I hope that it helps.

Community
  • 1
  • 1
jvrdelafuente
  • 1,992
  • 14
  • 23
  • No, PushStreamContent is not the issue, as we can get the content perfectly fine, and good. I tried your code, and that did not work either. I guess maybe it is related to how I was invoking it? Can you show me your code of invoking it? – junli antolovich Feb 13 '15 at 14:51
  • How are you doing the call? You should be able to call that using the browser. If it works you know that the problem is in your client code. @junliantolovich – jvrdelafuente Feb 13 '15 at 14:59
  • I think that in this other question can be useful to solve your problem: http://stackoverflow.com/questions/28421480/how-to-download-memory-stream-object-via-angularjs-and-webaapi2/28428474#28428474 @junliantolovich – jvrdelafuente Feb 13 '15 at 15:03
  • If you add your client code, I will try to find out why it is not working. – jvrdelafuente Feb 13 '15 at 15:08
  • from web page:$(document).ready(function () { $("#button2").click(function () { var file = $('#file2').val(); $.get('http://localhost:49161/api/FileDownload', { filen: file }, function (data) { alert(data); } ); }); – junli antolovich Feb 13 '15 at 15:11
  • 2
    window.open(url); Thats the code that you have to use to download de document for your client. @junliantolovich – jvrdelafuente Feb 13 '15 at 18:15
0

Open The result in a new tab.

window.open("/api/GetFile/" + vm.testReaderId);

Api :

[HttpGet]
[Route("api/TestReader/GenerateExcelTemplateForStudentsGrade/{testReaderId}")]
public HttpResponseMessage GetFile(long testReaderId)
{
HttpResponseMessage result = null;
result = Request.CreateResponse(HttpStatusCode.Gone);
result = Request.CreateResponse(HttpStatusCode.OK);
byte[] b = studentWorbook.SaveToStream().ToArray();
result.Content = new ByteArrayContent(b);
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
string name = "StudentValue";
result.Content.Headers.ContentDisposition.FileName = name + ".xls";
return result;
}
M Komaei
  • 7,006
  • 2
  • 28
  • 34