0

I have the following ASP.NET 4 code I found that I tried converting to ASP.NET 5 RC1 / ASP.NET Core

public async Task MyActionName(MyViewModel viewModel)
{
   //some stuff
   int accountId=1;

   string _contentDisposition =
   string.Format("attachment; filename=portfolio-inquiry-{0}.xlsx",
    accountId.ToString());

   Response.ContentType =
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
   Response.AddHeader("content-disposition", _contentDisposition);
   Response.BinaryWrite(_xlPackage.GetAsByteArray());
}

There is a GitHub answer posted that says for ASP.NET 5 I need to use

await context.Response.Body.WriteAsync(buffer, 0, buffer.Length);

So I change it for ASP.NET 5 to (not sure if it is correct)

public async Task MyActionName(MyViewModel viewModel)
{
   //some stuff
   int accountId=1;

   string _contentDisposition =
   string.Format("attachment; filename=portfolio-inquiry-{0}.xlsx", accountId.ToString());

   var buffer = _xlPackage.GetAsByteArray();
   await HttpContext.Response.Body.WriteAsync(buffer, 0, buffer.Length);

}

My view looks like this

<form action="@(Url.Action("MyActionName", "Controller"))" data-ajax="true" data-ajax-method="POST" method="post">
    //form inputs
    <button type="submit" class="btn btn-primary">Get file</button>
</form>

And the code run through without an error. However since the HttpContext.Response.Body.WriteAsync or the old return is void I'm not sure how to return it back to my MVC view as the above code runs through correctly but since it doesn't return anything to the view, the view doesn't get the file.

I have run Fiddler to see if anything gets sent to the browser from the controller but nothing. In visual Studio I can step through all the code. I think a possible issue is because ASP.NET 5 doesn't have Response.AddHeader method so I excluded that line to see if it still works.

I then tried to convert it to a file and send that back to the view by chaning

 return File(buffer, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

and changed my method return type to async Task<FileResult>.

However the result is still the same. Code steps through the controller but doesn't return anything to the view. Fiddler picks up nothing. Debugging picks up no error. JavaScript console throws no error.

greay
  • 1,725
  • 5
  • 18
  • 37
  • You are downloading the file as an attachment, you shouldn't need to return it to the view. A normal form submit without ajax should work for this. – Rhumborl Mar 01 '16 at 09:35
  • Possible duplicate of [Returning a file to View/Download in ASP.NET MVC](http://stackoverflow.com/questions/5826649/returning-a-file-to-view-download-in-asp-net-mvc) – Panagiotis Kanavos Mar 01 '16 at 09:42
  • Return a FileResult with one of the [File](https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.file(v=vs.118).aspx) method overloads. Views are only for rendering. When you want to return Json, a file or some other representation, you need to return the appropriate Result instance – Panagiotis Kanavos Mar 01 '16 at 09:43
  • I did change it to return FileResult but it behaves the same e.g. view gets nothing – greay Mar 01 '16 at 11:58

2 Answers2

0

Can you try this:

public async Task MyActionName(MyViewModel viewModel)
{
   //some stuff
   int accountId=1;

   string _contentDisposition = string.Format("attachment; filename=portfolio-inquiry-{0}.xlsx", accountId.ToString());

   Response.Clear();
   Response.BufferOutput = true;
   Response.Buffer = true;
   Response.AddHeader("content-disposition", _contentDisposition);
   Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
   Response.BinaryWrite(_xlPackage.GetAsByteArray());
   Response.End();

   //redirect to where you want to be seen in view.
   return Redirect("Index"); 
}
jomsk1e
  • 3,585
  • 7
  • 34
  • 59
  • My code is slightly different as I use ASP.net 5. However I added the redirect and it still doesn't send the file – greay Mar 01 '16 at 11:55
0

I did something really stupid.

My form had unobtrusive ajax enabled and I never handled the return ajax return.

If a file is returned you don't need to make an ajax POST a normal POST will do.

I changed my form to

 <form action="@(Url.Action("MyActionName", "Controller"))" data-ajax="true" data-ajax-method="POST" method="post">

to

 <form action="@(Url.Action("MyActionName", "Controller"))" method="post">

and it works

greay
  • 1,725
  • 5
  • 18
  • 37