Forgot to update this, but now I have found a way to solve this problem:
There will be two APIs, one (POST) will remember the data that will be used in processing, and another (GET) that will distribute the file.
POST:
[HttpPost] public async Task<HttpResponseMessage> BuildFile(FileParameters fileParams) { var guid = Guid.NewGuid().ToString(); if (fileParams!= null) { await Task.Run(() => FileContents.Add(guid, fileParams)); return this.Request.CreateResponse(HttpStatusCode.OK, new { Value = guid }); } return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid data"); }
In AngularJs, remember the returned guid and pass this to another api:
location.href = '/api/file/generatefile' + '?guid=' + generatedGuidFromAPI + '&reportName=' + $scope.reportName;
And here is the generatefile API controller in MVC:
Get
[HttpGet] public async Task<HttpResponseMessage> GenerateFile(string guid, string reportName) { byte[] output = null; if (FileContents.ContainsKey(guid)) { await Task.Run(() => { using (var stream = new MemoryStream()) { this.CreateFile(FileContents[guid], stream); stream.Flush(); output = stream.ToArray(); } }); } FileContents.Remove(guid); if (output != null) { var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(output) }; result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = reportName + ".csv" }; return result; } return this.Request.CreateErrorResponse(HttpStatusCode.NoContent, "No record found"); }
using location.href will cause the browser to automatically download the file, asking him to save it or not.
Roj Beraña Jan 04 '14 at 6:09 a.m. 2014-01-04 06:09 a.m.
source share