zoukankan      html  css  js  c++  java
  • ASP.NET MVC 4 Ajax上传文件

    这两天一直纠结着表单的问题。想在一个表单里实现三个功能:

    1. 输入查询条件,点击查询;
    2. 导出查询数据;
    3. 上传文件;

    方法有很多,乱花渐欲迷人眼,尝试了很多,无果。大致说的是,给不同按钮写js代码,在js代码里设置url和get、post、multipart/form-data等属性。看到猎风的demo很不错:

     1 <script type="text/javascript">  
     2     function save()
     3     {   
     4         document.form1.action="a.asp";
     5         document.form1.submit();
     6     }
     7     
     8     function send()
     9     {
    10         document.form1.action="b.asp";
    11         document.form1.submit();
    12     }   
    13 </script>
    14 </head>
    15 <body>
    16 <form name="form1">
    17   <input type="text" name="username" value="scott">
    18   <input type="button" value="发送" onclick="send();">
    19   <input type="button" value="保存" onclick="save();">
    20 </form>
    21 </body>

    很清晰的代码!可惜我用不上。

    后来终于做了一个艰难的决定——上传文件用一个form,另两个功能用一个form,总共两个form。

    上传文件用MVC的html辅助方法吧:

    @using (@Html.BeginForm("ImportExcel0", "BOM",  FormMethod.Post, new { id = "UploadForm", enctype = "multipart/form-data" })) 
    { 
         <input type="file" id="FileUpload1" name="FileUpload1" />
         <input id="import" type="submit" value="导入Excel" />
    }

    哦,这个虽然可以上传文件,但是刷新页面会重复提交。好吧,用Ajax.BeginForm,这个是异步的应该不会导致重复提交。折腾许久发现这个Ajax.BeginForm根本不能上传文件!要异步上传文件,还得用jquery.form.js这个插件。http://malsup.com/jquery/form/

    Let's go !

    HTML:

    1 <form id="UploadForm" name="UploadForm" action="/BOM/ImportExcel0/" method="post" enctype="multipart/form-data">
    2     <input type="file" id="FileUpload1" name="FileUpload1" />
    3     <input id="import" type="submit" value="上传" />
    4 </form>

    Javascript:

     1  $("#UploadForm").ajaxForm({
     2             iframe: true,
     3             dataType: "json",
     4             beforeSubmit: function () {
     5                 if ($('#FileUpload1').val() == '') {
     6                     alert('请选择文件!');
     7                     return false;
     8                 }
     9             },
    10             success: function (result) {
    11                 $("#UploadForm").resetForm();
    12                 var DialogVars = $.parseJSON(result);//响应信息
    13                 if (result.success) {
    14                     toastr.success(result.message, 'Success Message')
    15                     alert(result.message);
    16                     //导入成功后记录数没实时更新 
    17                     $("#list").trigger("reloadGrid");
    18                 }
    19                 else {
    20                     toastr.error(result.message, 'Error Message')
    21                     alert(result.message);
    22                 }
    23             },
    24             error: function (xhr, textStatus, errorThrown) {
    25                 $("#UploadForm").resetForm();
    26                 toastr.error('文档上传错误.', 'Error Message')
    27             }
    28         });

    这里有些东西后面介绍。

    Controller:

      public ActionResult ImportExcel0()
            {
                if (Request.Files["FileUpload1"] != null && Request.Files["FileUpload1"].ContentLength > 0)
                {
                    string fileName = System.IO.Path.GetFileName(Request.Files["FileUpload1"].FileName);
                    //string extension = System.IO.Path.GetExtension(fileName);
                    string serverPath = string.Format("{0}/{1}", Server.MapPath("~/Content/UploadedFolder"), fileName);
                    if (System.IO.File.Exists(serverPath))
                        System.IO.File.Delete(serverPath);
    
                    Request.Files["FileUpload1"].SaveAs(serverPath);
    
                    try
                    {
                        ImportExportData.ImportExcel(serverPath, "BOMs");
                        ViewBag.Msg = "good";
                        System.IO.File.Delete(serverPath);
                        return Json(new { success = true, message = "导入成功!", fileName = fileName });
                    }
                    catch (Exception ex)
                    {
                        ViewBag.Msg = ex.Message;
                        System.IO.File.Delete(serverPath);
                        return Json(new { success = false, message = "导入失败" + ex.Message, fileName = fileName });
                    }
                }
                return View("Index");
            }

    看起来还行,可以运行。但是问题接踵而来。

    1、在IE8里点击上传文件后,文本框内容不消失,如果继续点击上传按钮,还会上传一次。

    2、在IE8里上传成功后应该返回一个信息,这个信息是json格式的,但是IE8接收不到json格式的数据!实际情况是,当点击上传按钮后,本期望的弹出信息没看到反而出来一个下载提示:

    再次向IE致敬!

    寻寻觅觅,终于得知是ContentType问题,这个类型应该设置为text/html才行。这个是在服务端设置的,传给客户端后再转成json的格式来接收。

    再看Controller里的action:

     public ActionResult ImportExcel0()
            {
                if (Request.Files["FileUpload1"] != null && Request.Files["FileUpload1"].ContentLength > 0)
                {
                    string fileName = System.IO.Path.GetFileName(Request.Files["FileUpload1"].FileName);
                    //string extension = System.IO.Path.GetExtension(fileName);
                    string serverPath = string.Format("{0}/{1}", Server.MapPath("~/Content/UploadedFolder"), fileName);
                    if (System.IO.File.Exists(serverPath))
                        System.IO.File.Delete(serverPath);
    
                    Request.Files["FileUpload1"].SaveAs(serverPath);
    
                    try
                    {
                        ImportExportData.ImportExcel(serverPath, "BOMs");
                        ViewBag.Msg = "good";
                        System.IO.File.Delete(serverPath);
                        //为避免IE8出现下载文件提示,需将ContentType设置为"text/html"
                        JsonResult jt = Json(new { success = true, message = "导入成功!", fileName = fileName });
                        jt.ContentType = "text/html";
                        return jt;
                        //增加以上3行代码。注释以下1行代码
                        //return Json(new { success = true, message = "导入成功!", fileName = fileName });
                    }
                    catch (Exception ex)
                    {
                        ViewBag.Msg = ex.Message;
                        System.IO.File.Delete(serverPath);
                        JsonResult jt = Json(new { success = false, message = "导入失败" + ex.Message, fileName = fileName });
                        jt.ContentType = "text/html";
                        return jt;
                        //return Json(new { success = false, message = "导入失败" + ex.Message, fileName = fileName });
                    }
                }
                return View("Index");
            }

    这样一来居然把上面出现的两个问题同时解决了!

    本来对于清除input type=file的问题愁肠百转,找到一个方法看起来很厉害的样子:

    //清除file文本框的内容
        window.reset2 = function (e) {
            e.wrap('<form>').closest('form').get(0).reset();
            e.unwrap();
        }

    现在不用纠结了。

    注:

    javascript代码里有个toastr,这个是个信息提示插件,详情可见:http://kevintsengtw.blogspot.com/2013/03/aspnet-mvc-jquery-form-plugin.html#.UoYcWdLWamQ

    一些链接:

    http://blog.163.com/rihui_7/blog/static/212285143201361735143401/
    http://www.oschina.net/question/223750_123703
    http://my.oschina.net/wangr15/blog/160054

    深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法
    http://www.itivy.com/jquery/archive/2011/7/6/jquery-get-post-getjson-ajax.html

  • 相关阅读:
    图解设计模式-Visitor模式
    图解设计模式-Decorator模式
    图解设计模式-Strategy模式
    图解设计模式-Bridge模式
    HashMap源码
    LinkedList源码
    Vector源码
    ArrayList源码
    图解设计模式-Abstract Factory模式
    图解设计模式-Builder模式
  • 原文地址:https://www.cnblogs.com/ibgo/p/3427321.html
Copyright © 2011-2022 走看看