在"在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"/>

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

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

  1. SNF快速开发平台MVC-EasyUI3.9之-ueditor富文本编辑在 asp.net MVC下使用步骤

    mvc项目中用到了这个富文本编辑就试着把遇到的问题个使用步骤在这里记录一下,希望大家少走弯路. 1.首先我们先下载net版本的uediot 2.然后把整个文档拷贝到我们的项目中,记得是整个 把下载的文 ...

  2. ASP.NET MVC下的四种验证编程方式[续篇]

    在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注Validation ...

  3. ASP.NET MVC下的四种验证编程方式

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定 ...

  4. Response.End()在Webform和ASP.NET MVC下的表现差异

    前几天在博问中看到一个问题--Response.End()后,是否停止执行?MVC与WebForm不一致.看到LZ的描述后,虽然奇怪于为何用Response.End()而不用return方式去控制流程 ...

  5. ASP.NET MVC下的四种验证编程方式[续篇]【转】

    在<ASP.NET MVC下的四种验证编程方式> 一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式(“手工验证”.“标注ValidationAttribute特性”.“ ...

  6. ASP.NET MVC下的四种验证编程方式【转】

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...

  7. ASP.NET MVC下使用AngularJs语言(六):获取下拉列表的value和Text

    前面Insus.NET有在Angularjs实现DropDownList的下拉列表的功能.但是没有实现怎样获取下拉列表的value和text功能. 下面分别使用ng-click和ng-change来实 ...

  8. ASP.NET MVC下使用AngularJs语言(五):ng-selected

    这次学习ng-selected语法,这个是为DropDownList下拉列表显示默认选项. 演示从下面步骤开始 1,新建一个model: 上面#14行代码的property,数据类型为bool.即是存 ...

  9. ASP.NET MVC下使用AngularJs语言(二):ng-click事件

    程序用户交互,用户使用mouse点击,这是一个普通的功能. 在angularjs的铵钮点击命令是ng-click. 创建Angularjs的app使用前一篇<ASP.NET MVC下使用Angu ...

随机推荐

  1. MySQL5.7 GTID在线开启与关闭【转】

    当前场景   当前某些业务还有未开启GTID服务组,升级5.7后,如何检测是否符合开启GTID条件,如何在线修改切换使用GTID:已经升级5.7后,已经开启GTID,如何快速回滚后退: 线上gtid如 ...

  2. 移动端HTML5开发 选择方案

    如今出现了大量的CSS前端框架,但真正优秀的框架只有少数几个. 本文将会比较其中五个最佳的框架.每个框架都有自己的优点和缺点,以及具体的应用领域,你可以根据自己的具体项目需求进行选择.此外,许多选项都 ...

  3. 一步一步学习IdentityServer3 (4)

    其实上述例子 很多都很找到 但是在实际生态环境中给例子有很多不一样的地方 比如自定已登录界面怎么做? 怎么访问自己的用户数据库实现登录? 怎么在接口中使用,在接口中又怎么实现与Idr3结合授权? 等等 ...

  4. linux修改文件读写执行权限命令chmod

    之前用chmod的时候都是简单的类似下面这样使用: $ file 也有时候可能会修改一个目录下所有子目录和文件: $ directory -R 也知道3个数字(例子中的755)分别代表赋予 “文件属主 ...

  5. nginx静态资源缓存策略配置

    1. 问题-背景 以前也经常用nginx,但用的不深,通常是简单的设置个location用来做反向代理.直到今天给客户做项目碰到缓存问题:客户有个app,只是用原生做了个壳,里面的内容都是用h5写的, ...

  6. 2017, X Samara Regional Intercollegiate Programming Contest 题解

    [题目链接] A - Streets of Working Lanterns - 2 首先将每一个括号匹配串进行一次缩减,即串内能匹配掉的就匹配掉,每个串会变成连续的$y$个右括号+连续$z$个左括号 ...

  7. 027.Zabbix的定期备份

    一 数据库备份及恢复 1.1:全库备份 [root@zabbix01 ~]# mysqldump -uroot -p123456 --opt zabbix > zabbix.sql [root@ ...

  8. InnoDB的锁机制浅析(一)—基本概念/兼容矩阵

    InnoDB锁的基本概念 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key ...

  9. IP基础知识与分配实现

    一.IP寻址 1.划分网络ID和主机ID的最初方案是使用地址分类. 2.A类:0.0.0.0-127.255.255.255 B类:128.0.0.0-191.255.255.255 C类:192.0 ...

  10. Web服务器指纹识别工具httprint

    Web服务器指纹识别工具httprint   在Web渗透测试中,准确判断服务器的类型直接影响后期渗透测试的成功率.Kali Linux提供了专门的Web服务器指纹识别工具Httprint.该工具根据 ...