zoukankan      html  css  js  c++  java
  • AngularJS之WebAPi上传(十)

    前言

    前面一系列我们纯粹是讲AngularJS,在讲一门知识时我们应该结合之前所学综合起来来做一个小的例子,前面我们讲了在MVC中上传文件的例子,在本节我们讲讲如何利用AngularJS在WebAPi中如何上传,来巩固下WebAPi并结合AngularJS中对应的一些组件学习下。

    AngularJS Upload Files for WebAPi

    (一)在WebAPi中我们如何获得上传本地文件的物理路径呢?需要实现此类: MultipartFormDataStreamProvider ,从该类中获取上传文件的物理路径并返回。如下:

        public class UploadMultipartFormProvider : MultipartFormDataStreamProvider
        {
            public UploadMultipartFormProvider(string rootPath) : base(rootPath) { }
    
            public override string GetLocalFileName(HttpContentHeaders headers)
            {
                if (headers != null &&
                    headers.ContentDisposition != null)
                {
                    return headers
                        .ContentDisposition
                        .FileName.TrimEnd('"').TrimStart('"');
                }
    
                return base.GetLocalFileName(headers);
            }
        }

    (二)为避免有些浏览器不支持多个文件上传我们通过实现 ActionFilterAttribute 特性来加以判断,如下:

        public class MimeMultipart : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                if (!actionContext.Request.Content.IsMimeMultipartContent())
                {
                    throw new HttpResponseException(
                        new HttpResponseMessage(
                            HttpStatusCode.UnsupportedMediaType)
                    );
                }
            }
    
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
    
            }
        }

    以上两个类为我们在WebAPi中上传提供一个保障。接下来我们需要的是如何利用AngularJS来上传。

    在AngularJS中上传需要用到 ng-file-upload 组件,而非 angularFileUpload 组件,在此之前一直是利用angularFileUpload组件,但是后来逐步迁移并且命名为ng-file-upload组件。同时为了一些加载效果如在github中顶部有加载线的过程,决定也在这里实现一下看看【说明:上传过程用到angular-loading-bar(加载)和ng-file-upload(上传)组件】。

    脚本

    (1)为了重用,我们将加载组件进行封装。

     //common.load.js
    (function () { 'use strict'; angular .module('common.load', [ 'angular-loading-bar', 'ngAnimate' ]); })();

    (2)启动加载线。

    //loadBarCtrl.js
    (function (app) { "use strict"; app.controller("loadCtrl", loadCtrl); function loadCtrl(cfpLoadingBar) { cfpLoadingBar.start(); } })(angular.module("common.load"));

    (3)上传文件代码

     //fileUploadCtrl.js
    (function (app) { 'use strict'; app.controller('fileUploadCtrl', fileUploadCtrl); fileUploadCtrl.$inject = ['$scope', '$http', '$timeout', 'Upload']; function fileUploadCtrl($scope, $http, $timeout, Upload, cfpLoadingBar) { $scope.upload = []; $scope.UploadedFiles = []; $scope.startUploading = function ($files) { for (var i = 0; i < $files.length; i++) { var $file = $files[i]; (function (index) { $scope.upload[index] = Upload.upload({ url: "/api/upload", method: "POST", file: $file, withCredentials: false }).progress(function (evt) { }).success(function (data, status, headers, config) { $scope.UploadedFiles.push({ FileName: data.FileName, FilePath: data.LocalFilePath, FileLength: data.FileLength }); cfpLoadingBar.complete(); }).error(function (data, status, headers, config) { }); })(i); } } } })(angular.module("common.load"));

    (4)加载主模块以及依赖模块。

     //app.js
    (function () { 'use strict'; angular .module('angularUploadApp', [ 'ngRoute', 'ngFileUpload', 'common.load' ]) .config(config) config.$inject = ['$routeProvider']; function config($routeProvider) { $routeProvider .when('/', { templateUrl: '../../app/templates/fileUpload.html', controller: 'fileUploadCtrl' }) .otherwise({ redirectTo: '/' }); } })();

    界面 

    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
        <link href="~/Content/loading-bar.min.css" rel="stylesheet" media="all" />
    </head>
    <body ng-app="angularUploadApp" ng-controller="loadCtrl">
        <nav class="navbar navbar-default" role="navigation">
    
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="http://www.cnblogs.com/createmyself">Angular File WebAPi Upload by <i style="color:#2da12d;font-weight:bolder;">xpy0928</i></a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
    
            </div>
    
        </nav>
        <div class="container">
            <div ng-include src="'../../app/templates/fileUpload.html'"></div>
        </div>
        <script src="../../Scripts/jquery-1.10.2.min.js"></script>
        <script src="../../Scripts/angular.min.js"></script>
        <script src="../../Scripts/angular-animate.min.js"></script>
        <script src="../../Scripts/angular-route.js"></script>
        <script src="../../app/plugins/loading-bar.min.js"></script>
        <script src="../../app/modules/common.load.js"></script>
        <script src="../../Scripts/ng-file-upload.min.js"></script>
        <script src="../../app/app.js"></script>
        <script src="../../app/controllers/loadBarCtrl.js"></script>
        <script src="../../app/controllers/fileUploadCtrl.js"></script>
    </body>
    </html>

    模板页:

    <div class="row" ng-controller="fileUploadCtrl">
        <div class="col-xs-3">
            <div>
                <input type="file" accept="images/*" ngf-pattern="'.png,.jpg,.gif'" ngf-select="startUploading($files)" multiple>
            </div>
        </div>
        <div class="col-xs-9">
            <div class="panel-body">
                <div class="panel panel-default" ng-repeat="uploadedFile in UploadedFiles track by $index">
                    <div class="panel-heading">
                        <strong>{{uploadedFile.FileName}}</strong>
                    </div>
                    <div class="panel-body">
                        <div class=" media">
                            <a class="pull-left" href="#">
                                <img class="media-object" width="100" ng-src="../uploadimages/{{uploadedFile.FileName}}" />
                            </a>
                            <div class="media-body">
                                <div class="lead" style="font-size:14px;color: crimson;500px;word-wrap:break-word">{{uploadedFile.FilePath}}</div>
                            </div>
                        </div>
                    </div>
                    <div class="panel-footer">
                        图片总字节: <span style="color:black">{{uploadedFile.FileLength}}</span>
                    </div>
                </div>
            </div>
    
        </div>
    </div>

    后台api服务:

        [RoutePrefix("api/upload")]
        public class FileUploadController : ApiController
        {
            [Route("")]
            [MimeMultipart]
            public async Task<FileUploadResult> Post()
            {
                var uploadPath = HttpRuntime.AppDomainAppPath + "UploadImages";
                if (!Directory.Exists(uploadPath))
                    Directory.CreateDirectory(uploadPath);
                var multipartFormDataStreamProvider = new UploadMultipartFormProvider(uploadPath);
                await Request.Content.ReadAsMultipartAsync(multipartFormDataStreamProvider);
    
                string _localFileName = multipartFormDataStreamProvider
                    .FileData.Select(multiPartData => multiPartData.LocalFileName).FirstOrDefault();
    
                return new FileUploadResult
                {
                    LocalFilePath = _localFileName,
    
                    FileName = Path.GetFileName(_localFileName),
    
                    FileLength = new FileInfo(_localFileName).Length
                };
            }
        }

    首先我们来看看例子搭建的结构:

    生成界面效果:

     

    下面我们来演示下最终效果:

     

    总结

    (1)在WebAPi中用到路由特性时,若在控制器中如  [RoutePrefix("api/upload")] 此时在方法中若未有  [Route("")] 此时在上传的url必须显示添加Post如: url: "/api/upload/post" 若添加则不用显示添加方法名。

    (2)在angular中加载模板为

     <div ng-include src="''"></div> 【注】:src中要加单引号,否则出错
     
    或者
    
     <div ng-include></div>

    (3)对于在WebAPi中上传可以参看此链接,更加详细。

    WebAPi:https://github.com/stewartm83/angular-fileupload-sample

    对于AngularJS组件中的加载和上传还有更多用法,可以参看如下链接:

    ng-file-upload:https://github.com/danialfarid/ng-file-upload

    angular-loading-bar:https://github.com/chieffancypants/angular-loading-bar

  • 相关阅读:
    基于redis实现的延迟消息队列
    Redis实现求交集操作结果缓存的设计方案
    限流算法之漏桶算法、令牌桶算法
    Apache设置防DDOS模块mod_evasive
    FastCGI技术
    详解强大的SQL注入工具——SQLMAP
    nginx根据域名做http,https分发
    Nginx配置SSL证书部署HTTPS网站
    JProfiler学习笔记
    Mysql压测工具mysqlslap 讲解
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/5565125.html
Copyright © 2011-2022 走看看