Now in the preceding code, we have taken the reference of the two JavaScript files:
MyApp.Js and FileUploader.JS.
- var MyApp = angular.module('MyApp', []);
Again add another JavaScript file within the same folder named FileUploader.JS and define the controller in that file as in the following.
- MyApp.controller("FileUploder", ['$scope', '$http', '$timeout', '$window',
- function ($scope, $http, $location, $timeout, $window) {
- $scope.AttachStatus = "";
- }
- ]);
Now depending on the normal functionality of file upload control of HTML, when we click on the Choose File button, it opens the file open dialog and allows us to select file. Now our objective is, after selecting the file, it will automatically read the file and show the file size in the page. For this purpose, we called the onchange event of the file upload control and written the following code.
- $scope.setFiles = function (element) {
- $scope.$apply(function (scope) {
- $scope.AttachStatus = "";
- $scope.files = []
- for (var i = 0; i < element.files.length; i++) {
- $scope.files.push(element.files[i])
- }
- $scope.progressVisible = false
- });
- }
This function takes the instance of the control as an argument and updates the scope with the file detail information, such as file name, file size in bytes and so on.
Now our next objective is to upload the file using the Web API so that this specific file can be copied and saved in a specific location. For this, we already created a button name Upload. We need to click on this button for uploading. When we click this button, it will call an AngularJs function that internally redirects to the Web API controller to copy and save the file into a specific location. (Here I am using Temporary Internet Files folder for the location.)
Now write the following code first into the fileupload.js file.
- $scope.fnUpload = function () {
- var fd = new FormData()
- for (var i in $scope.files) {
- fd.append("uploadedFile", $scope.files[i])
- }
- var xhr = new XMLHttpRequest();
- xhr.addEventListener("load", uploadComplete, false);
- xhr.open("POST", "http://localhost:53154/api/FileUploader/AttachFile", true);
- $scope.progressVisible = true;
- xhr.send(fd);
- }
-
- function uploadComplete(evt) {
- $scope.progressVisible = false;
- if (evt.target.status == 201) {
- $scope.FilePath = evt.target.responseText;
- $scope.AttachStatus = "Upload Done";
- alert($scope.FilePath);
- }
- else {
- $scope.AttachStatus = evt.target.responseText;
- }
- }
In the fnUpload button, it creates an instance of FormData object and stores the file information within the FormData and sends the data to the webapi as a XMLHttpRequest. And the uploadComplete function checks if the Web API returns a status code 201 (in other words success) or not.
Now for the Web API code. For that, we will add a controller file within the controller folder named FileUploaderController and write the following code in that file.
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using System.Web;
- using System.Web.Http;
-
- namespace FileUploader.Controllers
- {
- public class FileUploaderController : ApiController
- {
- [HttpPost]
- public HttpResponseMessage AttachFile()
- {
- HttpResponseMessage result = null;
- var httpRequest = HttpContext.Current.Request;
- if (httpRequest.Files.Count > 0)
- {
- var docfiles = new List<string>();
- foreach (string file in httpRequest.Files)
- {
- var postedFile = httpRequest.Files[file];
- string filePath = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.InternetCache), postedFile.FileName));
- postedFile.SaveAs(filePath);
-
- docfiles.Add(filePath);
- }
- result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
- }
- else
- {
- result = Request.CreateResponse(HttpStatusCode.BadRequest);
- }
- return result;
- }
- }
- }
Now our file upload part is complete. Now, if we run the project and select a file and click on the upload button it will display the file location in an alert box. We can check that the file is physically there.
Now to download a file, we already created a button named DownLoad in the HTML page. Now we will write the code for this download button in the fileuploader.js file.
- $scope.fnDownLoad = function () {
- debugger;
- $scope.FileExt = $scope.files[0].name.substr($scope.files[0].name.length - 4);
- $scope.GenerateFileType($scope.FileExt);
- $scope.RenderFile();
- }
-
- $scope.RenderFile = function () {
- var s = "http://localhost:53154/api/FileUploader/DownLoadFile?"
- + "FileName=" + $scope.files[0].name
- + "&fileType=" + $scope.FileType;
- $window.open(s);
- }
-
- $scope.GenerateFileType = function (fileExtension) {
- switch (fileExtension.toLowerCase()) {
- case "doc":
- case "docx":
- $scope.FileType = "application/msword";
- break;
- case "xls":
- case "xlsx":
- $scope.FileType = "application/vnd.ms-excel";
- break;
- case "pps":
- case "ppt":
- $scope.FileType = "application/vnd.ms-powerpoint";
- break;
- case "txt":
- $scope.FileType = "text/plain";
- break;
- case "rtf":
- $scope.FileType = "application/rtf";
- break;
- case "pdf":
- $scope.FileType = "application/pdf";
- break;
- case "msg":
- case "eml":
- $scope.FileType = "application/vnd.ms-outlook";
- break;
- case "gif":
- case "bmp":
- case "png":
- case "jpg":
- $scope.FileType = "image/JPEG";
- break;
- case "dwg":
- $scope.FileType = "application/acad";
- break;
- case "zip":
- $scope.FileType = "application/x-zip-compressed";
- break;
- case "rar":
- $scope.FileType = "application/x-rar-compressed";
- break;
- }
- }
In the preceding code, we first created the file extension from the file name and then set the file MIME type depending on the file extension. Then we will again call the Web API get method to download the file where we the file name and file extension as parameter.
The file download method is as in the following.
- [HttpGet]
- public HttpResponseMessage DownLoadFile(string FileName, string fileType)
- {
- Byte[] bytes = null;
- if (FileName != null)
- {
- string filePath = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.InternetCache), FileName));
- FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
- BinaryReader br = new BinaryReader(fs);
- bytes = br.ReadBytes((Int32)fs.Length);
- br.Close();
- fs.Close();
- }
-
- HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
- System.IO.MemoryStream stream = new MemoryStream(bytes);
- result.Content = new StreamContent(stream);
- result.Content.Headers.ContentType = new MediaTypeHeaderValue(fileType);
- result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
- {
- FileName = FileName
- };
- return (result);
- }
This get method actually reads the file from its physical location (where the file was saved during the upload) and then converts the file into a byte array using file stream reader. Then return the byte content as a HttpResponseMessage to the browser so that the browser can download that file directly.
The following is the complete code of the Fileuploader.js file.
- MyApp.controller("FileUploder", ['$scope', '$http', '$timeout', '$window',
- function ($scope, $http, $location, $timeout, $window) {
- $scope.AttachStatus = "";
-
- $scope.fnUpload = function () {
- var fd = new FormData()
- for (var i in $scope.files) {
- fd.append("uploadedFile", $scope.files[i])
- }
- var xhr = new XMLHttpRequest();
- xhr.addEventListener("load", uploadComplete, false);
- xhr.open("POST", "http://localhost:53154/api/FileUploader/AttachFile", true);
- $scope.progressVisible = true;
- xhr.send(fd);
- }
-
- function uploadComplete(evt) {
- $scope.progressVisible = false;
- if (evt.target.status == 201) {
- $scope.FilePath = evt.target.responseText;
- $scope.AttachStatus = "Upload Done";
- alert($scope.FilePath);
- }
- else {
- $scope.AttachStatus = evt.target.responseText;
- }
- }
-
- $scope.fnDownLoad = function () {
- debugger;
- $scope.FileExt = $scope.files[0].name.substr($scope.files[0].name.length - 4);
- $scope.GenerateFileType($scope.FileExt);
- $scope.RenderFile();
- }
-
- $scope.RenderFile = function () {
- var s = "http://localhost:53154/api/FileUploader/DownLoadFile?"
- + "FileName=" + $scope.files[0].name
- + "&fileType=" + $scope.FileType;
- $window.open(s);
- }
-
- $scope.GenerateFileType = function (fileExtension) {
- switch (fileExtension.toLowerCase()) {
- case "doc":
- case "docx":
- $scope.FileType = "application/msword";
- break;
- case "xls":
- case "xlsx":
- $scope.FileType = "application/vnd.ms-excel";
- break;
- case "pps":
- case "ppt":
- $scope.FileType = "application/vnd.ms-powerpoint";
- break;
- case "txt":
- $scope.FileType = "text/plain";
- break;
- case "rtf":
- $scope.FileType = "application/rtf";
- break;
- case "pdf":
- $scope.FileType = "application/pdf";
- break;
- case "msg":
- case "eml":
- $scope.FileType = "application/vnd.ms-outlook";
- break;
- case "gif":
- case "bmp":
- case "png":
- case "jpg":
- $scope.FileType = "image/JPEG";
- break;
- case "dwg":
- $scope.FileType = "application/acad";
- break;
- case "zip":
- $scope.FileType = "application/x-zip-compressed";
- break;
- case "rar":
- $scope.FileType = "application/x-rar-compressed";
- break;
- }
- }
-
- $scope.setFiles = function (element) {
- $scope.$apply(function (scope) {
- $scope.AttachStatus = "";
- $scope.files = []
- for (var i = 0; i < element.files.length; i++) {
- $scope.files.push(element.files[i])
- }
- $scope.progressVisible = false
- });
- }
-
- }
- ]);
There is one thing we need to remember. In a normal scenario, Visual Studio or ASP.NET allows us to upload a file of a maximum size of 4 MB. If we want to upload a larger file then we need to change the web.config file as in the following.
- <httpRuntime targetFramework="4.5" maxRequestLength="104857600" />
-
- <security>
- <requestFiltering>
- <requestLimits maxAllowedContentLength="104857600" maxQueryString="104857600"/>
- </requestFiltering>
- </security>
First, provide a maxRequestLength value in byte format that we want.
Secondly, add the requestFiletering tab within security as specified above.
Now, our task is complete and we will run the project. The following is the final output.