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;width: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

时间: 2024-08-03 15:14:54

AngularJS之WebAPi上传(十)的相关文章

webApi上传服务,可重命名,可创建文件夹

webApi上传服务,根据FileName重命名,根据Path创建文件夹 /// <summary> /// 上传文件 /// </summary> /// <returns></returns> [HttpPost, Route("upload")] public IHttpActionResult UploadFile() { string defaultPath = ConfigurationManager.AppSettings[

用angularjs进行文件上传

文件上传页面三要素: 1.  form表单提交方式一定是post 2.  form表单的enctype一定是multipart/form-data 3.  form表单中一定要有一个input的type是 file 文件上传一定要有的jar Commons-io和commons-fileupload Springmvc文件上传: 1.  springmvc.xml中一定要有 多媒体解析器 <bean id="multipartResolver" class="org.s

WebAPI上传大文件

今天在研究WebAPI的上传与下载,作为Rest的框架,更多是面向资源,就其本身来说,是不会涉及也不应该涉及到大文件的处理,具体多大呢,也就是ASP.NET的限值2G. ASP.NET的pipeline对于上传文件一般的处理流程是接收到文件,放到内存中,我们也一般只处理后续的流程,例如存入硬盘等等. 目前想象的一个场景是上传一个大文件,后续处理可能有多种.如果并发数过多,肯定会造成内存溢出,所以参考资料与琢磨,搞定了这个问题. 但是场景本身是有一定问题的,这纯属个人爱好在玩,真实场景来说文件不宜

通过AngularJS实现图片上传及缩略图展示

从项目中截出的代码 HTML部分: <section> <img src="image/user-tuijian/tuijian_banner.png" /> <div> <form ng-submit="submit_form()"> <input type="text" name="aaa" placeholder="商品名称:" ng-model=

Angularjs+Nodejs图片上传

1.插件 (1) :angular插件 ng-file-upload (2) : nodejs插件connect-multiparty 2.html <input type="file"  ngf-select ng-model="files" ngf-multiple="true" /> 3.配置 var app = angular.module('fileUpload', ['ngFileUpload']);可以参考https:/

webapi上传文件

必须组件 jquery.min.js和jquery.form.js <div class="demo"> <p>说明:示例中只允许上传gif/jpg格式的图片,图片大小不能超过500k.</p> <div class="btn"> <span>添加附件</span> <input id="fileupload" type="file" name=&q

(转)WebApi 上传文件

本文转载自:http://www.cnblogs.com/zj1111184556/p/3494502.html public class FileUploadController : ApiController { public async Task<HttpResponseMessage> Post() { // 检查是否是 multipart/form-data if (!Request.Content.IsMimeMultipartContent("form-data&quo

angularJs多文件上传

<input type="file" id="file{{$index}}" class="file{{$index}}" ngf-select ngf-change="cacScriptEditVm.views.uploadAttach($files)" multiple/> <div class="form-group" ng-repeat="item in cacScrip

AngularJS 文件上传控件 ng-file-upload

网上可以找到的 AngularJS 的文件上传控件有两个: angular-file-upload:https://github.com/nervgh/angular-file-upload ng-file-upload:https://github.com/danialfarid/ng-file-upload 这两个非常类似,连js文件的结构都是一样的.核心的js是.min.js,还都有一个-shim.min.js,用来支持上传进度条和上传暂停等高级功能. 按道理讲shim.js应该是可加可不