Wednesday, 25 January 2017

Upload multiple files along with user data to WebApi using Angular Js

In this post we are going to see how to upload multiple files along with user data to Webapi. For this first we have to create a web api controller, in that create a Post method which reads the files and user data, then return the response to the user.


Then we will create controller .


    public class BlogController : ApiController
    {
        public string Get()
        {
            return "testing";
        }

        [CheckMimeMultiPart]
        public async Task<FilePostResult> Post()
        {
            try
            {
                var path = HttpContext.Current.Server.MapPath("~/img");
                var sprovide = new MultipartFormStreamProvider(path);
                await Request.Content.ReadAsMultipartAsync(sprovide);
             
                var trackingid = sprovide.FormData.GetValues("trackingid")
                    .FirstOrDefault();
                var description = sprovide.FormData.GetValues("description")
                    .FirstOrDefault();

                var localfilename = sprovide.FileData.Select(x => x.LocalFileName)
                                   .FirstOrDefault();

                var fileinfo = new FileInfo(localfilename);
                var response = new FilePostResult();

                response.FileName = fileinfo.Name;
                response.Size = fileinfo.Length;
                response.Url = Request.RequestUri.GetLeftPart(UriPartial.Authority) 
                               +"/img/" + response.FileName; 
                response.TrackingId = trackingid;
                response.Description = description;

                return response;                               
                 
            }catch(Exception ex)
            {
                return new FilePostResult()
                {
                    FileName = "",
                    Size =0,
                    Url =                                           
                    Request.RequestUri.GetLeftPart(UriPartial.Authority)                   
                };
            }

        }

    }


Filter Mimetype check:

    public class CheckMimeMultiPart : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.Request.Content.IsMimeMultipartContent())
            {
               throw new     
                 HttpResponseException(System.Net.HttpStatusCode.UnsupportedMediaType);
            }
        }

    }


  public class FilePostResult
    {
        public string Description { set; get; }

        public string TrackingId { set; get; }
           
        public string FileName { set; get; }

        public string Url
        {
            set;get;
        }

        public long Size { set; get; }

    }


add Reference  Angular-file-upload.js, angular-file-upload-shim.js developed by Danial

    <script src="~/Scripts/angular.js" type="text/javascript"></script>
    <script src="~/Scripts/angular-route.js" type="text/javascript"></script>
    <script src="~/Scripts/angular-file-upload.js" type="text/javascript"></script>
    <script src="~/Scripts/angular-file-upload-shim.js" type="text/javascript"></script>
    <script src="~/App/app.js" type="text/javascript"></script>



Upload control Directive:

var rgapp = angular.module('rgapp', ['angularFileUpload']);

 rgapp.directive('fileuploadForm', ['$upload'function ($upload) {
    return {
        scope: {
            asyncurl: '@',
            method: '@',
            successCallback: '&',
            fileselectCallback:'&',
            errorCallback: '&',
            inputData:'='
        },
        restrict: 'E',
        templateUrl:'../App/templates/upload.html',
        link: function (scope, element, attr, cntrl) {

            var uploadingFiles = [];
            var uploadFileHandlers = [];

            scope.uploadedFilesString = '';

            scope.uploading = function(){
                for (var i = 0; i < uploadingFiles.length; i++) {
                    var _file = uploadingFiles[i];

                    (function (indx) {
                        uploadFileHandlers[indx] = $upload.upload({
                            url: attr.asyncurl,
                            method: attr.method,
                            file: _file,
                            data: scope.inputData
                        })
                            .progress(function (prg) {
                                console.log("index " + indx);
                                console.log(prg);
                             })
                            .success(function (data, status, headers, config) {
                                if (scope.successCallback)
                                scope.successCallback({ data: data, 
                                      status: status, 
                                      headers: headers, 
                                      config: config });
                            })
                            .error(function (data, status, headers, config) {
                                if (scope.errorCallback)
                                scope.errorCallback({ data: data, 
                                       status: status, 
                                       headers: headers, 
                                       config: config });
                            });

                   })(i);

                }
            }

            scope.abort = function (indx) {
                uploadFileHandlers[indx].abort();
            }

            scope.uploadedFiles = function (files) {
                uploadingFiles = files;
                scope.uploadedFilesString = '';
                for (var i = 0; i < uploadingFiles.length; i++) {
                    scope.uploadedFilesString += uploadingFiles[i].name + ";";
                }
                if (scope.fileselectCallback)
                    scope.fileselectCallback({ files: files });
            }
           
            scope.browseFiles = function () {
                document.getElementById('rgfile').click();               
            }
           
        }
    }
}]);


Template:

<div>
    <div class="">
        <div class="form-inline" style="padding:20px">
            <label>Files :</label>
            <input type="text" ng-model="uploadedFilesString" class="form-control" />
            <button ng-click="browseFiles()" class="btn btn-sm">Browse</button>
            <button ng-click="uploading()" class="btn btn-sm btn-success">Upload</button>
        </div>
        <div class="form-group">
            <input  type="file" style="display:none" ng-file-select="uploadedFiles($files)"                      class="form-control" id="rgfile"
                    ng-model="user.file" multiple />
        </div>         
    </div>

</div>



Controller:



var rgapp = angular.module('rgapp', ['angularFileUpload']);

rgapp.controller('blogcontroller', ['$scope','$upload',function ($scope,$upload) {

    $scope.Files = [];
    $scope.FilesData = [];
    $scope.filedata = { trackingid:'', description:''};

    $scope.success = function (data,status,headers,config) {
        console.log('config');
        console.log(config);
        $scope.FilesData.push(data);
    }

    $scope.error = function (data,status,headers,config) {
        console.log('error');
        console.log(config);
    }

    $scope.uploadfiles = function (files) {
        console.log(files);
    }

    

}]);



Index:


<div ng-controller="blogcontroller">
    <div>
        <h3>Angular js File Upload</h3>
    </div>
    <div>
        <div class="form-inline">
            <label>Tracking id :</label>
            <input type="text" class="form-control" ng-model="filedata.trackingid" />
        </div>
        <br />
        <div class="form-inline">
            <label>Description :</label>
            <input type="text" class="form-control" ng-model="filedata.description" />
        </div>
        <div style="margin-left:25px;">
            <fileupload-form asyncurl="~/api/Blog"
                             method="post"
                             input-data="filedata"
                             fileselect-callback="uploadfiles(files)"
                             success-callback="success(data,status,headers,config)"
                             error-callback="error(data,status,headers,config)">
             </fileupload-form>
        </div>
    </div>

    <div>
        <table ng-show="FilesData.length > 0" class="table table-bordered">
            <thead>
                <tr>
                    <th>Tracking Id</th>
                    <th>Description</th>
                    <th>Image</th>
                </tr>
            </thead>
            <tr ng-repeat="item in FilesData">
                <td>{{item.TrackingId}}</td>
                <td>{{item.Description}}</td>
                <td>
                    <div>
                        <img style="width:150px;" ng-src="{{item.Url}}" 
                             alt="{{item.FileName}}" />
                        <div style="display:inline-block">
                            <span style="padding:5px;">
                                <strong>FileName :</strong>  {{item.FileName}}</span>
                            <br />
                            <span style="padding:5px;">
                                <strong>Size :</strong> {{item.Size}}</span>
                        </div>
                    </div>
                </td>
            </tr>
        </table>
    </div> 

</div>

















From this post you can learn how to upload a multiple files along with user data to WebApi using angular js



No comments:

Post a Comment