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


    在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片。但还有一个重要的话题是需要面对的,那就是图片脏数据问题。


    假设用户添加产品信息,并且上传了图片,可之后用户没有点击页面上的添加按钮,这就导致上传图片成为"脏数据",存在着却一直不会被使用。解决这个问题的大致思路是:

     

    ○ 在上传图片的时候,把图片保存到一个临时文件夹,或者叫缓存文件夹
    ○ 当用户真正保存的时候,再把临时文件夹的图片拷贝到最终目标文件夹

     

    假设,有这样的一个Model,它的ImageUrl属性,用来存放图片真正的相对路径。

        public class ImgVm
    
        {
    
            [Required(ErrorMessage = "必填")]
    
            public string ImageUrl { get; set; }
    
        }

    在HomeController中,存在如下的一些Action:

     

    ○ 提供一个显示上传页面的Action,并且是ImgVm类型的强类型视图,ImgVm的ImageUrl属性用来存放上传图片的相对路径
    ○ 提供一个接收ImgVm类型的Action,把临时文件夹内的图片复制到目标文件夹内,并且给ImgVm的ImageUrl属性赋上新的图片相对路径

     

            public ActionResult Index()
    
            {
    
                return View(new ImgVm());
    
            }
    
            [HttpPost]
    
            public ActionResult Index(ImgVm imgVm)
    
            {
    
                if (ModelState.IsValid)
    
                {
    
                    //目标文件夹路径
    
                    string pathForRealSaving = Server.MapPath("~/RealUpload/");
    
                    //目标文件夹内的用户文件夹路径
    
                    string pathForRealUserSaving = Server.MapPath("~/RealUpload/User001/");
    
                    //当前文件路径
    
                    string existingFilePath = Server.MapPath(imgVm.ImageUrl);
    
                    //当前文件名,根据文件路径获得
    
                    string existingFileName = Path.GetFileName(existingFilePath);
    
                    if (CreateFolderIfNeeded(pathForRealSaving))
    
                    {
    
                        if (CreateFolderIfNeeded(pathForRealUserSaving))
    
                        {
    
                            //根据当前文件路径获取当前文件
    
                            var existingfile = Path.GetFullPath(existingFilePath);
    
                            //获取目标文件夹内的目标文件
    
                            var realfile = Path.Combine(pathForRealUserSaving, existingFileName);
    
                            //把临时文件内的图片复制到目标文件夹内
    
                            System.IO.File.Copy(existingfile, realfile, true);
    
                            
    
                            //保存新的图片相对路径
    
                            imgVm.ImageUrl = "RealUpload/User001/" + existingFileName;
    
                        }
    
                    }
    
                  
    
                    return View("showimg", imgVm);
    
                }
    
                else
    
                {
    
                    return Index(imgVm);
    
                }
    
            }
    


    Home/Index.cshtml中多了在上传图片成功后给id为ImageUrl隐藏域赋值的部分。

     

    @model MvcApplication10.Models.ImgVm
    
    @{
    
        ViewBag.Title = "Index";
    
        Layout = "~/Views/Shared/_Layout.cshtml";
    
    }
    
    <style type="text/css">
    
        #msg {
    
            color: red;
    
        }
    
    </style>
    
    @using (Html.BeginForm("Index", "Home", FormMethod.Post, new {id = "addForm", @class = "form-horizontal"}))
    
    {
    
        <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>  
    
        
    
        <div>
    
            @Html.HiddenFor(m => m.ImageUrl)
    
            <input type="submit" value="提交"/>
    
        </div>
    
    }
    
     
    
    @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);
    
                                    //清空上传文件框内容
    
                                    $('#file').val('');
    
                                    //给隐藏域赋值
    
                                    $('#ImageUrl').val(data.filepath);
    
                                } 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>
    
    }
    

     

    还有一个Home/showimg.cshtml视图,用来显示新的(相对临时文件夹中的那张图片)图片。

    @model MvcApplication10.Models.ImgVm
    
    @{
    
        ViewBag.Title = "showimg";
    
        Layout = "~/Views/Shared/_Layout.cshtml";
    
    }
    
    <h2>showimg</h2>
    
    <img src="@Model.ImageUrl"/>
    

     

    当然,存放上传图片的临时文件夹是可以随时清理的。

     

  • 相关阅读:
    JMM简述
    spring简读
    Linux常用命令
    基于java的八大排序实现
    数据库事务说明
    BIO、NIO、AIO区别与联系
    ThreadLocal 是什么?有哪些使用场景?
    ConcurrentHashMap 和 Hashtable 比较,为什么推荐使用ConcurrentHashMap?
    sychronized设计原理
    MySQL索引详解
  • 原文地址:https://www.cnblogs.com/darrenji/p/4200837.html
Copyright © 2020-2023  润新知