在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片

在"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传"一文中,使用JSAjaxFileUploader这款插件实现了单文件上传,在chrome, firefox下运行良好,但在某些版本的IE浏览器(比如IE8,IE9)下却无法正常运行,这可能是因为JSAjaxFileUploader插件在编写时没有考虑到某些低版本IE浏览器导致的。本篇,就在ASP.NET MVC4下实现单个图片上传,具体功能包括:

1、在客户端选择图片,并限制图片的大小和格式
2、在客户端上传图片,并显示预览图
3、在服务端限制图片的大小和格式
4、在服务端保存图片时,把图片裁剪成某个固定尺寸

本篇源码在:https://github.com/darrenji/FileUploadInMVC

实现的大致思路是:

○ 客户端限制图片大小和格式,通过写一个jQuery插件来实现
○ 服务端实现图片裁剪,通过使用ImageSize组件来实现

首先是一个用来承载上传信息的类:

    public class UploadFileResult
    {
        //带后缀的名称,比如xxx.jpg
        public string FileName { get; set; }

        //图片的字节数
        public int Length { get; set; }

        //图片的类型:image/jpeg
        public string Type { get; set; }

        public bool IsValid { get; set; }
        public string Message { get; set; }

        //图片的完整路径:~/AjaxUpload/20141112_large.jpg
        public string FilePath { get; set; }
    }


在HomeController中,需要提供一个接收前端上传文件并返回json格式的Action方法,还需要提供一个根据文件名删除图片的Action方法。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ImageResizer;
using MvcApplication10.Models;

namespace MvcApplication10.Controllers
{
    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        //接收上传图片
        [HttpPost]
        public ActionResult UploadFile()
        {
            //允许的图片格式
            var allowedExtensions = new[] { ".png", ".gif", ".jpg", ".jpeg" };

            //返回给前台的结果,最终以json返回
            List<UploadFileResult> results = new List<UploadFileResult>();

            //遍历从前台传递而来的文件
            foreach (string file in Request.Files)
            {
                //把每个文件转换成HttpPostedFileBase
                HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;

                //如果前台传来的文件为null,继续遍历其它文件
                if (hpf.ContentLength == 0 || hpf == null)
                {
                    continue;
                }
                else
                {
                    if (hpf.ContentLength > 1024*1024) //如果大于规定最大尺寸
                    {
                        results.Add(new UploadFileResult()
                        {
                            FileName = "",
                            FilePath = "",
                            IsValid = false,
                            Length = hpf.ContentLength,
                            Message = "图片尺寸不能超过1024KB",
                            Type = hpf.ContentType
                        });
                    }
                    else
                    {
                        var extension = Path.GetExtension(hpf.FileName);

                        if (!allowedExtensions.Contains(extension))//如果文件的后缀名不包含在规定的后缀数组中
                        {
                            results.Add(new UploadFileResult()
                            {
                                FileName = "",
                                FilePath = "",
                                IsValid = false,
                                Length = hpf.ContentLength,
                                Message = "图片格式必须是png、gif、jpg或jpeg",
                                Type = hpf.ContentType
                            });
                        }
                        else
                        {
                            //给上传文件改名
                            string date = DateTime.Now.ToString("yyyyMMddhhmmss");
                            //目标文件夹的相对路径 ImageSize需要的格式
                            string pathForSaving = Server.MapPath("~/AjaxUpload/");
                            //目标文件夹的相对路径 统计文件夹大小需要的格式
                            string pathForSaving1 = Server.MapPath("~/AjaxUpload");

                            //在根目录下创建目标文件夹AjaxUpload
                            if (this.CreateFolderIfNeeded(pathForSaving))
                            {
                                //保存小图
                                var versions = new Dictionary<string, string>();
                                versions.Add("_small", "maxwidth=400&maxheight=250&format=jpg");
                                //versions.Add("_medium", "maxwidth=200&maxheight=200&format=jpg");
                                //versions.Add("_large", "maxwidth=600&maxheight=600&format=jpg");

                                //保存各个版本的缩略图
                                foreach (var key in versions.Keys)
                                {
                                    hpf.InputStream.Seek(0, SeekOrigin.Begin);
                                    ImageBuilder.Current.Build(new ImageJob(
                                        hpf.InputStream,
                                        pathForSaving + date + key, //不带后缀名的图片名称
                                        new Instructions(versions[key]),
                                        false,//是否保留原图
                                        true));//是否增加后缀
                                }

                                results.Add(new UploadFileResult()
                                {
                                    FileName = date + "_small" + ".jpg",
                                    FilePath = Url.Content(String.Format("~/AjaxUpload/{0}", date + "_small" + ".jpg")),
                                    IsValid = true,
                                    Length = hpf.ContentLength,
                                    Message = "上传成功",
                                    Type = hpf.ContentType
                                });
                            }

                        }
                    }
                }
            }

            return Json(new
            {
                filename = results[0].FileName,
                filepath=results[0].FilePath,
                isvalid=results[0].IsValid,
                length=results[0].Length,
                message=results[0].Message,
                type=results[0].Type
            });
        }

        //根据文件名删除文件
        [HttpPost]
        public ActionResult DeleteFileByName(string smallname)
        {
            string pathForSaving = Server.MapPath("~/AjaxUpload");
            System.IO.File.Delete(Path.Combine(pathForSaving, smallname));
            return Json(new
            {
                msg = true
            });
        }

        //根据相对路径在项目根路径下创建文件夹
        private bool CreateFolderIfNeeded(string path)
        {
            bool result = true;
            if (!Directory.Exists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (Exception)
                {
                    result = false;
                }
            }
            return result;
        }
    }
}


在Home/Index.cshtml中,使用checkFileTypeAndSize.js插件(在"写一个限制上传文件大小和格式的jQuery插件"中所写的插件)来限制上传图片的大小和格式,使用FormData对象来接收图片文件并传递给服务端,客户端接收到服务端json数据动态创建表格行把预览图显示出来。

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<style type="text/css">
    #msg {
        color: red;
    }

</style>

<form id="file_upload_form" method="post" enctype="multipart/form-data" action="">
    <input name="file" id="file" size="27" type="file" />
    <img src="~/images/ajax-loader.gif" id="indicator" style="display: none;" />
    <br />
    <div id="imgArea">
        <table id="tbl">
            <tbody>
            </tbody>
        </table>
    </div>
    <div>
        <span id="msg"></span>
    </div>
</form>


@section scripts
{
    <script src="~/Scripts/checkFileTypeAndSize.js"></script>
    <script type="text/javascript">
        $(function() {
            $("#file").checkFileTypeAndSize({
                allowedExtensions: [‘jpg‘,‘jpeg‘,‘gif‘,‘png‘],
                maxSize: 1024, //最大允许1024KB,即1MB
                success: function () {
                    //显示进度提示
                    $(‘#indicator‘).css("display", "block");

                    //清空提示内容
                    $(‘#msg‘).text(‘‘);

                    if ($(‘#fn‘).text().length > 0) {
                        //删除图片
                        deleteImg();
                    }

                    //上传文件数据准备
                    var fd = new FormData();
                    fd.append(‘image‘, $(‘#file‘)[0].files[0]);

                    $.ajax({
                        url: ‘@Url.Action("UploadFile","Home")‘,
                        type: "POST",
                        data: fd,
                        contentType: false,
                        cache: false,
                        processData: false,
                        dataType: ‘json‘,
                        success: function (data) {

                            //隐藏进度提示
                            $(‘#indicator‘).css("display", "none");


                            if (data.isvalid) {
                                //$(‘#fileTemplate‘).tmpl(data).appendTo(‘#imgArea‘);
                                createTableTr();
                                $(‘#thumb‘).attr(‘src‘, data.filepath);
                                $(‘#fn‘).text(data.filename);

                            } else {
                                $(‘#msg‘).text(data.message);
                             }
                        }
                     });

                },
                extensionerror: function () {
                    //alert(‘允许的格式为:jpg,jpeg,gif,png‘);
                    $(‘#msg‘).text(‘允许的格式为:jpg,jpeg,gif,png‘);
                    return;
                },
                sizeerror: function () {
                    //alert(‘最大尺寸1024KB,即1MB‘);
                    $(‘#msg‘).text(‘最大尺寸1024KB,即1MB‘);
                    return;
                }
            });
        });

        //删除图片
        function deleteImg() {
            $.ajax({
                cache: false,
                url: ‘@Url.Action("DeleteFileByName", "Home")‘,
                type: "POST",
                data: { smallname: $(‘#fn‘).text() },
                success: function (data) {
                    if (data.msg) {
                        $(‘#fn‘).parent().parent().remove();
                    }
                },
                error: function (jqXhr, textStatus, errorThrown) {
                    alert("出错了 ‘" + jqXhr.status + "‘ (状态: ‘" + textStatus + "‘, 错误为: ‘" + errorThrown + "‘)");
                }
            });
        }

        //创建表格
        function createTableTr() {
            var table = $(‘#tbl‘);
            table.append("<tr><td><img id=‘thumb‘ /></td><td colspan=‘2‘><span id=‘fn‘></span></td></tr>");
        }
    </script>

}




时间: 2024-11-11 17:21:58

在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片的相关文章

Asp.net mvc 3 实现进度条上传思路[转]

最近在做asp.net mvc 大文件上传,但是每次大文件上传的响应时间都很长,没有提示就给不了用户良好的体验,所以想了想还是必须在文件上传时显示进度条,但是asp.net默认的文件上传管道是无法显示进度条的.所以就必须自己手动创建一个接收管道.实现的方式有2种,一种是写一个类继承IHttpModule接口然后实现其中的方法,还有一种就是直接在Global.asax里面的Application_BeginRequest写上传文件的方法. 在写文件接收方法的时候应该分块来接收文件,然后在同时保存文

ASP.NET MVC使用jQuery无刷新上传

昨晚网友有下载了一个jQuery无刷新上传的小功能,他尝试搬至ASP.NET MVC应用程序中去,在上传死活无效果.Insus.NET使用Teamviewer远程桌面,操作一下,果真是有问题.网友是说,把源代码一一照搬的复制.难道它不能移值至ASP.NET MVC应用程序吗?Insus.NET想了一下,源代码是html+ashx的,它一定能的. 网友发送能正常运行的代码给Insus.NET...... 重点的script文件:http://download.cnblogs.com/insus/M

ASP.NET MVC 5 with EF 6 上传文件

    参考   ASP.NET MVC 5 with EF 6 - Working With Files Rename, Resize, Upload Image (ASP.NET MVC) ASP.NET MVC Image Uploader

ASP.NET MVC,文件的两种上传方式

文件类型可以更换,在后台保存的时候更换下保存格式@*视图*@<div id="checkQuestionnaireAdd">    <form id="editform">        <input id="id" type="hidden" name="id" value="0" />        <table class="t1

ASP.NET MVC WebAPI实现文件批量上传

工作中学习,学习中记录~~~~~~ 最下面附上demo 任务需求:需要做一个apI接口让C#的程序调用实现批量文件的上传. 难度: 没有做过通过API上传文件的...之前做过网站前后台上传. 首先当然是百度...没人教就自己百度学习学习,大佬还是多.环境还是好. 先了解WEBAPI,然后了解如何上传文件,最后实现批量上传~~~~ 不会的按照上面步骤遨游百度....我直接上代码,也许写的不咋地,但是先记录下来后续自己继续学习~~~~~~~ 首先WEBAPI部分: WInfrom部分 最后附上dem

springboot项目图片上传,回显;使用外部静态资源路径回显图片

//前端图片是Base64字符串形式传递图片参数:需要用Base解密,写入到本地磁盘中 public String upload(String string){ 解析图片(Base64): response.setHeader("Access-Control-Allow-Origin","*"); // 第二个参数填写允许跨域的域名称,不建议直接写 "*" response.setHeader("Access-Control-Allow

【前端插件】图片上传插件收集

http://tpl.9iphp.com/146.htmlHTML5实现的图片上传预览功能 http://www.dropzonejs.com/ 图片上传预览. http://segmentfault.com/a/1190000000754560HTML5 本地裁剪图片并上传至服务器(老梗) http://elemefe.github.io/image-cropper/图片裁剪 上传 http://veerkat.me/blog/posts/HTML5-tu-pian-shang-chuan-y

在ASP.NET MVC下有关上传图片脏数据的解决方案

在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片.但还有一个重要的话题是需要面对的,那就是图片脏数据问题. 假设用户添加产品信息,并且上传了图片,可之后用户没有点击页面上的添加按钮,这就导致上传图片成为"脏数据",存在着却一直不会被使用.解决这个问题的大致思路是: ○ 在上传图片的时候,把图片保存到一个临时文件夹,或者叫缓存文件夹○ 当用户真

java图片上传(mvc)

最近有开始学起了java,好久没写文章了,好久没来博客园了.最近看了看博客园上次写的图片上传有很多人看,今天在一些篇关于java图片上传的.后台接收用的是mvc.不墨迹了,直接上图. 先看目录结构.idea开发. 一.图片上传还是使用的这款jq插件.前端部署这款插件,不用说了吧.效果图       二.前台代码只需要盖一个位置.因为是比较好用的插件.插件样式自行修改. 三.后台代码. 后面看不见的. 这个图片上传主要是自己写了几个函数.让图片储存更加方便.分成了年月日储存.但是后期遍历比较困难,