This short walk-through is intended for those who work with WebApi and want to perform file download using Knockout or JQuery. While working on a project that uses Knockout.js for front end scripting and Asp.Net Web API as back-end service layer, we had to implement file downloading functionality using Ajax. Lets Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
[HttpGet] //Returns FileStream if file exists public HttpResponseMessage DownloadDocument(string fileUrl) { try { Stream stream = FileHelper.GetFilesStream(fileUrl); HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK) result.Content = new StreamContent(stream); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition.FileName = "fileNameOfYourChoice"; return result; } catch (NotFoundException exception) { Request.CreateErrorResponse(HttpStatusCode.NotFound, "File Not Found"); } catch (Exception exception) { Request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception.Message); } } |
This method in Api returns a FileStream, sets ContentDisposition and ContentType to tell browser the type of content is a file and browser popups save file dialog. GetFileStream method is defined in a Helper class that just converts a file into filestream
|
public class FileHelper { public static Stream GetFilesStream(string fileUrl) { if (File.Exists(fileUrl)) { return new FileStream(fileUrl, FileMode.Open); } throw new NotFoundException("File not found"); } } |
Knockout Devs Knockout developers have to create a view and a viewModel. The viewModel will expose a caller for API while the view will simply have an anchor tag which will have its click event bound to viewModel’s funtion. ViewModel will have the following caller function
|
this.downloadDocument = function(attachment) { var resourceUri = '/api/Documents/DownloadDocument?fileUrl = ' + attachment.fileUrl; window.href.location = resourceUri; }; |
While the view’s anchor tag will look like
|
<a href = "" data-bind= "click: $parent.downloadDocument" > Download </a> |
JQuery Devs […]