• 在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

    1

     

    实现的大致思路是:

     

    ○ 客户端限制图片大小和格式,通过写一个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>
    
    }
    

     

  • 相关阅读:
    A+B Problem
    迭代平方根
    猴子报数
    分数求和
    猴子吃桃
    钻石
    杨辉三角形
    MYSQL 5.7 修改密码、登录问题
    SQL 语句 explain 分析
    重构CMDB,避免运维之耻
  • 原文地址:https://www.cnblogs.com/darrenji/p/4197172.html
Copyright © 2020-2023  润新知