9

Created wep api in asp.net 5. I am tring to return file response for Post request. But instead of file the response looks like `

{
  "version": {
    "major": 1,
    "minor": 1,
    "build": -1,
    "revision": -1,
    "majorRevision": -1,
    "minorRevision": -1
  },
  "content": {
    "headers": [
      {
        "key": "Content-Disposition",
        "value": [
          "attachment; filename=test.pdf"
        ]
      },
      {
        "key": "Content-Type",
        "value": [
          "application/pdf"
        ]
      }
    ]
  },
  "statusCode": 200,
  "reasonPhrase": "OK",
  "headers": [],
  "requestMessage": null,
  "isSuccessStatusCode": true
}`

Code:

    public HttpResponseMessage 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));                 

                var result = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(System.IO.File.ReadAllBytes(file))
                };
                result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                {
                    FileName = "test.pdf"
                };
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                return result;

            }

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

    }

How can I return the real file as the response instead of JSON ?I am using Postman as test client.

Joonas Püüa
  • 370
  • 3
  • 5
  • 18

3 Answers3

4

used IActionResult instead of HttpResponseMessage. And returned FileStreamResult, and got it working.

Got a new problem, the file is not the one I open with the stream from server. But will create a new question for that.

Continues : Return file from ASP.NET 5 Web API

Thanks

Community
  • 1
  • 1
Joonas Püüa
  • 370
  • 3
  • 5
  • 18
3

This is the "low-level" HTTP approach, which should work with both ASP.NET WebAPI or ASP.NET MVC.

[HttpGet]
public HttpResponseMessage Download()
{
  var fs = new FileStream(myfileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 32768, true);
  var response = new HttpResponseMessage {
    Content = new StreamContent(fs);
  }
  response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
  response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
  return response;
}
Florian Winter
  • 4,750
  • 1
  • 44
  • 69
MoSad
  • 31
  • 2
  • Wouldn't `fs.Dispose()` close the file before WebAPI has a chance to use the file stream? If not, then how does `Dispose()` work in this scenario? – Florian Winter Jul 30 '19 at 11:01
  • To answer my question above: You do not need to (and probably shouldn't) call `Dispose` on the stream you pass to `StreamContent`. I will edit your answer. See https://stackoverflow.com/a/38788127/2279059 – Florian Winter Jul 30 '19 at 11:06
  • It's still not WebAPI, because `this.Request.CreateResponse` does not exist in a WebAPI controller. – Florian Winter Jul 30 '19 at 11:17
2

Does setting HttpContext.Response.ContentType = "application/pdf" help at all?

This should fit 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;                                
    }
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Ian Auty
  • 847
  • 7
  • 10
  • Does `"headers": [],` have anything populated now? As I can see from your initial post that it's empty. What build of asp.net 5 are you using, and is it full .net or coreclr? – Ian Auty Jan 18 '16 at 13:03
  • Nope, it remains empty. – Joonas Püüa Jan 18 '16 at 13:20
  • Full - dnx451 ,build rc1-final – Joonas Püüa Jan 18 '16 at 13:21
  • If I add the header manually to HttpResponseMessage like that: result.Headers.Add("Content-Type", "application/pdf"); it throws : "Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects." – Joonas Püüa Jan 18 '16 at 13:31