Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return file from ASP.NET 5 Web API

My previous question: How to return file from ASP.net 5 web api

I am trying to return a file as the response from Web API POST request.

I'm using dnx451 framework and rc1-final build. Controller method:

[HttpPost("")]
public ActionResult Post([FromBody]DocumentViewModel vm)
{
    try
    {
        if (ModelState.IsValid)
        {

            var Document = _repository.GetDocumentByGuid(vm.DocumentGuid, User.Identity.Name);
            var Params = Helper.ClientInputToRealValues(vm.Parameters, Document.DataFields);
            var file = Helper.GeneratePdf(Helper.InsertValues(Params, Document.Content));
            FileStream stream = new FileStream(file,FileMode.Open);

            return File(stream, "application/pdf", "test.pdf");

        }

    }
    catch (Exception ex)
    {
        Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return null;
    }
    Response.StatusCode = (int)HttpStatusCode.BadRequest;
    return null;

}

As result I get a file with name "response". After saving it as pdf i try to open it, and it says it is damaged. Hope you can help me. I am using Postman as test client.

Thanks

like image 874
Joonas Püüa Avatar asked Jan 18 '16 14:01

Joonas Püüa


3 Answers

Please see my answer in the other post: Return file as response

For reference, I think this fits your needs:

public FileResult TestDownload()
{
    HttpContext.Response.ContentType = "application/pdf";
    FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes("YOUR PATH TO PDF"), "application/pdf")
    {
        FileDownloadName = "test.pdf"
    };

    return result;                                
}
like image 107
Ian Auty Avatar answered Nov 17 '22 23:11

Ian Auty


I've just had this problem and found a solution. As long as you have an absolute path to your file, then you can return a PhysicalFileResult and explicitly set the Content-Disposition header on the Response, like so:

[HttpGet("{key}")]
public IActionResult Get(string key)
{
    var file = _files.GetPath(key);

    var result = PhysicalFile(file.Path, "text/text");

    Response.Headers["Content-Disposition"] = new ContentDispositionHeaderValue("attachment")
    {
        FileName = file.Name
    }.ToString();

    return result;
}

Using PhysicalFile also has the advantage that all the asynchronous streaming of bytes and so on is taken care of by the framework.

like image 12
Mark Rendle Avatar answered Nov 17 '22 23:11

Mark Rendle


It's perhaps better to consider the use the FileStreamResult action result.

This has the advantage of not requiring that the entire file contents be held in memory which, depending on the size of the file, level of traffic, etc. could very easily lead to problems of scale.

Something like this:

[HttpGet]
public FileStreamResult DownloadFile()
{
    var Document = _repository.GetDocumentByGuid(vm.DocumentGuid, User.Identity.Name);
    var Params = Helper.ClientInputToRealValues(vm.Parameters, Document.DataFields);
    var file = Helper.GeneratePdf(Helper.InsertValues(Params, Document.Content));
    var stream = new FileStream(file,FileMode.Open);
    return new FileStreamResult(stream, "application/pdf")
    {
        FileDownloadName = "test.pdf"
    };
}
like image 2
Stewart_R Avatar answered Nov 17 '22 22:11

Stewart_R