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

  • 相关阅读:
    1046 Shortest Distance (20 分)(模拟)
    1004. Counting Leaves (30)PAT甲级真题(bfs,dfs,树的遍历,层序遍历)
    1041 Be Unique (20 分)(hash散列)
    1036 Boys vs Girls (25 分)(查找元素)
    1035 Password (20 分)(字符串处理)
    1044 Shopping in Mars (25 分)(二分查找)
    onenote使用小Tip总结^_^(不断更新中...)
    1048 Find Coins (25 分)(hash)
    三个故事
    领导者的举止
  • 原文地址:https://www.cnblogs.com/ibgo/p/3427321.html
Copyright © 2011-2022 走看看