Create
a database Named File Data as follows :
USE
[Employee]
GO
/******
Object: Table [dbo].[FileData] Script Date: 2/23/2018 10:31:24 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[FileData](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FileName] [nvarchar](50) NULL,
[FileDescription] [nvarchar](100) NULL,
[File] [nvarchar](max) NULL,
[FileType] [nvarchar](50) NULL,
CONSTRAINT
[PK_FileData] PRIMARY KEY
CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE
= OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON
[PRIMARY]
GO
Now
For uploading Files to Database Using AngularJS and WebApi
Create
a project in a solution (this project is for html and js files)
And
create a html file and write the below code :
index.html
<!DOCTYPE html>
<html ng-app="angularuploaddownloadfiles">
<head>
<meta charset="utf-8" />
<title>AngularJS
And WebAPI - Upload And Download Files</title>
<!--<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<script
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>-->
<!--If
No Net Connection-->
<!--
<link rel="stylesheet" href="" />-->
<link href="AngularJS-Scripts/css/bootstrap.min.css" rel="stylesheet" />
<script src="AngularJS-Scripts/js/angular.min.js"></script>
<script src="index.js"></script>
<script src="customdirectives.js"></script>
</head>
<body ng-controller="UploadDownloadFileController">
<form name="formvalidation" novalidate>
<div class="container">
<div class="col-sm-8 col-sm-offset-2">
<!--
Page Header -->
<div class="page-header"><h1>AngularJS And WebAPI - Upload And
Download Files</h1></div>
<div class="form-group">
<div class="row">
<div class="col-md-4">
<label>Upload :</label>
<input type="file" class="form-control" id="file1" name="file" ng-files="getFileDetails($files)" />
<span style="color:red;font-size:smaller;" ng-show="UploadFileLimit">{{FilesLimitErrorMessage}}</span>
</div>
<div class="col-md-5">
<label>File Description :</label>
<input class="form-control" name="filedescription" ng-model="FileDescription" />
</div>
<div class="col-md-3">
<button name="add" class="btn
btn-primary" ng-click="uploadFiles()">Add</button>
<button name="clear" class="btn
btn-danger" ng-click="ClearData()">Clear</button>
</div>
</div>
<div class="col-md-12
text-center">
<div class="row">
<span style="color:red;font-size:smaller"> The total limit of files to be upload is 10 MB.</span>
</div>
<div class="row">
<span style="color:red;font-size:smaller;">{{SelectFilesErrorMessage}}</span>
</div>
</div>
<div class="row">
<div id="UploadFilesList">
<table class="table
table-responsive">
<thead>
<tr>
<th>SNO</th>
<th>File Name</th>
<th>File Description</th>
<th>Action</th>
<th> </th>
</tr>
</thead>
<tr ng-repeat="file in files">
<td style="width:20%">{{$index + 1}}</td>
<td class="truncate" style="width:30%">{{ file.name.substr(0, file.name.lastIndexOf('.')).trunc(40) }}</td>
<td style="width:30%">{{ file.FileDescription }}</td>
<td style="width:20%">
<button class="btn
btn-primary btn-sm" ng-click="DeleteFile($index)">Delete</button>
</td>
</tr>
</table>
</div>
</div>
<div class="text-center">
<span ng-show="ShowLoader">
<img src="./images/loading.gif" class="img-loading" />
</span>
<span ng-show="ShowSuccessMessage" style="color:green;font-size:larger">{{SubmitFilesSucessMessage}}</span><br />
<span ng-show="ShowErrorFiles" style="color:red;font-size:larger">{{SubmitFilesErrorMessage}}</span><br />
<button class="btn
btn-primary btn-sm" ng-click="SubmitFiles()">Submit</button>
</div>
</div>
<div class="form-group">
<div class="row">
<div id="UploadFilesList">
<table class="table
table-responsive">
<thead>
<tr>
<th>SNO</th>
<th>File Name</th>
<th>File Description</th>
<th>Action</th>
<th> </th>
</tr>
</thead>
<tr ng-repeat="file in GetFileData">
<td>{{file.Id}}</td>
<td>{{file.FileName}}</td>
<td>{{ file.FileDescription }}</td>
<td>
<button ng-if="file.File!=null" class="btn
btn-primary btn-sm" ng-click="DirectDownloadFile(file.Id)">Download From Base64</button>
<p ng-if="file.File==null">No File Found</p>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
Now
create a js file and write the below code : that is containing with creation of
angularjs module and controller
index.js
var app = angular.module('angularuploaddownloadfiles', []);
app.controller('UploadDownloadFileController', function ($scope, $window, $http) {
var serviceBasePath = 'http://localhost:2653';
$scope.DirectDownloadFile = function (fileId) {
$http.get(serviceBasePath + '/api/Download/DirectDownloadFile?FileId=' + fileId, { responseType: 'arraybuffer' }).then(function (response) {
var filename = response.headers()['x-filename'] || ("Document_" + new Date() +
".pdf");
var contentType = response.headers()['content-type'];
var linkElement = document.createElement('a');
try {
var blob = new
Blob([response.data], { type: contentType });
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
linkElement.dispatchEvent(clickEvent);
} catch (ex) {
console.log(ex);
}
}, function (error) {
})
}
$scope.files
= [];
$scope.encodedbase64_file = [];
var fileSize = 0;
var fileSizeAdd = 0;
var FixedFileSize = 10485760;
////TO GET THE
FILE INFORMATION.
$scope.getFileDetails = function ($files) {
var allowfiles = 0;
fileSizeAdd = ($scope.files &&
$scope.files.length) ? fileSizeAdd : 0;
fileSize = ($scope.files &&
$scope.files.length) ? fileSize : 0;
$scope.$apply(function () {
$scope.UploadFileLimit = false;
$scope.FilesLimitErrorMessage = "";
})
$scope.SelectFilesErrorMessage = "";
var allowedFileFormats = ["jpg", "jpeg", "png", "pdf", "doc", "docx", "tiff", "tif", "bmp"];
if ($files &&
!$scope.SelectFilesErrorMessage) {
for (var i = 0; i
< $files.length; i++) {
if (fileSizeAdd == fileSize) {
fileSize =
parseFloat(fileSize) + parseFloat($files[i].size);
}
else {
if ($files[i].size < FixedFileSize)
fileSize = fileSizeAdd;
else fileSize = parseFloat(fileSize) +
parseFloat($files[i].size);
}
if (allowedFileFormats.indexOf($files[i].name.split(".").pop().toLowerCase()) >
-1) {
$scope.FilesLimitErrorMessage = "";
}
else {
$scope.FilesLimitErrorMessage = "Only jpg, jpeg, png, pdf, doc, docx, tiff, tif,
bmp files are allowed!";
break;
}
}
if (!$scope.FilesLimitErrorMessage) {
if (fileSize <= FixedFileSize) {
$scope.UploadFileLimit = false;
$scope.FilesLimitErrorMessage
= "";
$scope.filesList = [];
$scope.$apply(function () {
//// STORE THE FILE OBJECT IN AN ARRAY.
for (var i = 0; i < $files.length; i++) {
$scope.filesList.push($files[i])
setupReader($files[i]);
}
function setupReader(file) {
var name = file.name;
var reader = new
FileReader();
reader.onload = function (e) {
// get file content
$scope.encodedbase64_file.push(e.target.result);
}
reader.readAsDataURL(file);
}
$scope.disbleUploadFile
= true;
});
if ($scope.filesList)
$scope.btnAddDisable = false;
}
else {
//
angular.element("input[type='file']").val(null);
}
}
else {
$scope.FilesLimitErrorMessage =
"Only jpg,
jpeg, png, pdf, doc, docx, tiff, tif, bmp files are allowed!";
}
}
};
//// To
add the selected files to the grid table
$scope.uploadFiles = function () {
if ($scope.FileDescription) {
$scope.SelectFilesErrorMessage = "";
if ($scope.filesList && $scope.filesList.length &&
!$scope.SelectFilesErrorMessage) {
$scope.ValidationMessage = "";
var files = $scope.filesList;
fileSizeAdd = fileSize;
// $scope.files = files;
if (files && files.length > 0) {
var data = new FormData();
for (i = 0; i < files.length; i++) {
data.append("file" + i, files[i]);
files[i].FileDescription
= $scope.FileDescription;
$scope.files.push(files[i]);
$scope.filesList = [];
}
}
if ($scope.files && $scope.files.length > 0) {
$scope.btnAddDisable = true;
$scope.disbleUploadFile = true;
}
else {
$scope.btnAddDisable = false;
$scope.disbleUploadFile = false;
$scope.UploadFileLimit = true;
if (fileSize > FixedFileSize)
$scope.FilesLimitErrorMessage = $scope.FilesLimitErrorMessage ?
$scope.FilesLimitErrorMessage : "Files Limit
Exceeded 10 MB";
//// 10MB=10485760
Bytes (binary)
// angular.element("input[type='file']").val(null);
}
}
else {
if (fileSize > FixedFileSize) {
$scope.UploadFileLimit = true;
$scope.FilesLimitErrorMessage =
$scope.FilesLimitErrorMessage ? $scope.FilesLimitErrorMessage : "Files Limit Exceeded 10 MB";
}
else {
if ($scope.FilesLimitErrorMessage) {
$scope.UploadFileLimit
= true;
}
else {
$scope.UploadFileLimit
= false;
$scope.SelectFilesErrorMessage = "Please
Choose File To Upload";
}
}
}
}
else $scope.SelectFilesErrorMessage = $scope.SelectFilesErrorMessage ?
$scope.SelectFilesErrorMessage : "Please
Enter File Name";
};
/// To Delete
the files in the grid table by Id
$scope.DeleteFile = function (id) {
var index = -1;
var comArr = eval($scope.files);
for (var i = 0; i
< comArr.length; i++) {
if (i === id) {
index = i;
break;
}
}
if (index === -1) {
alert("Something gone wrong");
}
fileSize = parseFloat(fileSize) -
parseFloat($scope.files[index].size);
if (fileSize <= FixedFileSize) {
$scope.UploadFileLimit = false;
$scope.FilesLimitErrorMessage = "";
}
// var index = $scope.files.indexOf(name);
$scope.files.splice(index, 1);
if ($scope.files.length <= 0) {
$scope.btnAddDisable = false;
$scope.disbleUploadFile = false;
// angular.element("input[type='file']").val(null);
}
angular.element("input[type='file']").val();
}
//// To Submit
files to webapi
$scope.SubmitFiles = function () {
$scope.UploadFilesList = [];
$scope.UploadFileData = [];
$scope.FileTypeData = [];
$scope.ShowErrorFiles = false;
$scope.SubmitFilesErrorMessage = "";
for (var i = 0; i
< $scope.files.length; i++) {
$scope.UploadFileData.push($scope.encodedbase64_file[i].substring($scope.encodedbase64_file[i].indexOf("base64,") + 7));
$scope.FileTypeData.push($scope.encodedbase64_file[i].substring(5,
$scope.encodedbase64_file[i].indexOf(";")));
var FileDetails = {
File: $scope.UploadFileData[i],
FileName:
$scope.files[i].name.substr(0, $scope.files[i].name.lastIndexOf('.')),
FileDescription:
$scope.FileDescription,
FileType:
$scope.FileTypeData[i]
}
$scope.UploadFilesList.push(FileDetails);
}
if ($scope.UploadFilesList.length &&
!$scope.SelectFilesErrorMessage) {
$scope.ShowLoader = true;
$http.put(serviceBasePath + '/api/Upload/UploadFile',
$scope.UploadFilesList).then(function (response) {
$scope.ShowLoader = false;
$scope.ShowSuccessMessage = true;
$scope.SubmitFilesSucessMessage
= response.data;
$window.location.reload();
}, function (error) {
var errorMessages = [];
if (error.data && error.data.ModelState) {
for (var key in
error.data.ModelState) {
for (var i = 0; i < error.data.ModelState[key].length; i++) {
errorMessages.push(error.data.ModelState[key][i]);
}
}
// alert(errorMessages[0]);
$scope.ShowLoader = false;
$scope.ShowErrorFiles = true;
$scope.SubmitFilesErrorMessage = errorMessages[0];
}
else {
$scope.ShowLoader = false;
error ? ((error.data
&& error.data.Message) ? $scope.OrderListErrorMessage =
error.data.Message : $scope.OrderListErrorMessage = "The Request Is Invalid") :
$scope.OrderListErrorMessage = "Invalid
Request";
}
})
}
else {
$scope.SelectFilesErrorMessage =
$scope.SelectFilesErrorMessage ? $scope.SelectFilesErrorMessage : "Please Select A File";
}
}
//// To
Clear The popup controls when Open the popup
$scope.ClearData = function (item) {
angular.element("input[type='file']").val(null);
$scope.CaseId = item.SugarCRMCaseId;
$scope.files = [];
$scope.FileDescription = "";
$scope.disbleUploadFile = true;
$scope.FilesLimitErrorMessage = "";
$scope.btnAddDisable = false;
$scope.selectedCard = 0;
$scope.ShowSuccessMessage = false;
$scope.SubmitFilesSucessMessage = "";
$scope.SelectFilesErrorMessage = "";
}
var InIt = function () {
$http.get(serviceBasePath + '/api/Upload/GetAllData').then(function (response) {
$scope.GetFileData = response.data;
}, function (error) {
})
}
InIt();
});
Again
create another js file and code with custom directive to upload file and a
prototype to truncate the file name in html page
customdirectives.js
app.directive('ngFiles', ['$parse', function ($parse) {
function fn_link(scope, element, attrs) {
var onChange = $parse(attrs.ngFiles);
element.on('change', function (event) {
onChange(scope, { $files:
event.target.files });
});
};
return {
link: fn_link
}
}]);
/**
* extends string prototype object to get a
string with a number of characters from a string.
*
* @type {Function|*}
*/
//// to
truncate the given string
String.prototype.trunc
= String.prototype.trunc ||
function (n) {
// this will
return a substring and
// if its
larger than 'n' then truncate and append '...' to the string and return it.
// if its less
than 'n' then return the 'string'
return this.length
> n ? this.substr(0, n - 1) + '...' : this.toString();
};
And Now We have to
add another project to the same solution for WebAPI
Now create a
controllers named UploadController and DownloadController to receive the
request from Angularjs project and passes to WebAPI repository Where Repository
contains the business logic that we write the code for uploading files to
database and downloading files from database :
UploadController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using WebApi_UploadAndDownloadFiles.Models;
using WebApi_UploadAndDownloadFiles.Repository;
namespace WebApi_UploadAndDownloadFiles.Controllers
{
public class UploadController : ApiController
{
[HttpPut]
[Route("api/Upload/UploadFile")]
public async Task<IHttpActionResult> UploadFileToDB(List<UploadFilesList> uploadfiles)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
UploadRepository uploadRepo = new UploadRepository();
var result = await
uploadRepo.UploadFileToDB(uploadfiles);
return Ok(result);
}
catch (Exception ex)
{
return null;
}
}
[HttpGet]
[Route("api/Upload/GetAllData")]
public async Task<List<FileData>> GetAllData()
{
try
{
UploadRepository uploadRepo = new UploadRepository();
var result = await
uploadRepo.GetData();
return result;
}
catch (Exception ex)
{
return null;
}
}
}
}
DownloadController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using WebApi_UploadAndDownloadFiles.Repository;
namespace WebApi_UploadAndDownloadFiles.Controllers
{
public class DownloadController : ApiController
{
//File Download
By Converting Base64 Format
[HttpGet]
[Route("api/Download/DirectDownloadFile")]
public HttpResponseMessage DirectDownload(int FileId)
{
try
{
DownloadRepository downloadRepo = new DownloadRepository();
HttpResponseMessage result = downloadRepo.DirectDownloadFromBase64(FileId);
return result;
}
catch (Exception ex)
{
return this.Request.CreateResponse(HttpStatusCode.InternalServerError, ex);
}
}
}
}
And Now create a
folder named Repository and add the cs files named UploadRepository and
DownloadRepository and write business logic as below :
UploadRepository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using WebApi_UploadAndDownloadFiles.Models;
namespace WebApi_UploadAndDownloadFiles.Repository
{
public class UploadRepository
{
public async Task<List<FileData>> GetData()
{
using (FileEntities db = new FileEntities())
{
var fileData = db.FileDatas.Select(x => x).ToList();
return await Task.FromResult(fileData);
}
}
public async Task<string> UploadFileToDB(List<UploadFilesList> uploadfiles)
{
using (FileEntities db = new FileEntities())
{
for (int i = 0; i
< uploadfiles.Count(); i++)
{
FileData fileData = new FileData()
{
File =
uploadfiles[i].File,
FileDescription =
uploadfiles[i].FileDescription,
FileName =
uploadfiles[i].FileName,
FileType=
uploadfiles[i].FileType
};
db.FileDatas.Add(fileData);
}
db.SaveChanges();
}
return await Task.FromResult("Saved Successfully");
}
}
}
DownloadRepository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
namespace WebApi_UploadAndDownloadFiles.Repository
{
public class DownloadRepository
{
public HttpResponseMessage DirectDownloadFromBase64(int FileId)
{
using (FileEntities db = new FileEntities())
{
var fileData = db.FileDatas.Where(x => x.Id ==
FileId).FirstOrDefault();
string fileName = fileData.FileName;// +
".pdf";//"Document" + DateTime.Now.ToString("_MMMdd_yyyy_HHmmss")
+ ".pdf";
string base64formatstring = fileData.File;
if (!string.IsNullOrEmpty(base64formatstring))
{
byte[] bytes = Convert.FromBase64String(base64formatstring);
HttpResponseMessage
httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.Content
= new ByteArrayContent(bytes.ToArray());
httpResponseMessage.Content.Headers.Add("x-filename", fileName);
httpResponseMessage.Content.Headers.Add("Access-Control-Expose-Headers", "x-filename"); //Basically Adding
Access-Control-Expose-Headers helps to expose the custom headers to client
side.
// httpResponseMessage.Content.Headers.ContentType = new
MediaTypeHeaderValue("application/octet-stream");
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(fileData.FileType);
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName =
fileName;
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
}
}
return null;
}
}
}
As we have two projects in one solution, we have to start the two projects while running, for that right click on the solution file in Solution Explorer and Click on the 'Properties' and in the displayed window in 'Common Properties' select 'Startup Project' and in the displayed right side select the radio button 'Multiple startup projects' and select both project Action as 'Start'.
While Client request hits the webapi, then we will get CORS (Cross Origin Request Sharing) error, as below :
Failed to load http://localhost:2653/api/Upload/GetAllData: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:2647' is therefore not allowed access.
So, to prevent this we have to add the below code in Register() method in WebApiConfig static class :
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
i.e.,
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//To Convert To Json Format From Text Format
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
// To prevent the CORS error, if request comes from different host
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Output:-
If trying to add
other format of files than the mentioned format as below, It shows error
message:
var allowedFileFormats = ["jpg", "jpeg",
"png", "pdf", "doc", "docx", "tiff", "tif", "bmp"];
Now choose the file
to upload as below :
Now Click on Add button , then the File data is added to the list as below :
Now choose another file and add as below :
Now Click on submit button, then the data is added to the below grid as below :
Now click on download button, it will download the file to download folder as below :
Download Code From GitHub
Download Code From GitHub
No comments:
Post a Comment
Note: only a member of this blog may post a comment.