在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好,无刷新,带上传进度等等。在最近的一个webform开发项目中,我就是使用的Uploadify,虽然有些小瑕疵,但是基本上还是满意的(在webform中使用Uploadify可以参考《JQuery上传插件Uploadify使用详解》),所以当现在使用MVC开发的时候,自然将之作为首选。
首先引入js和css文件:
<script src="/Content/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script src="/Content/Scripts/swfobject.js" type="text/javascript"></script> <script src="/Content/Scripts/jquery.uploadify.v2.1.0.min.js" type="text/javascript"></script> <link href="/Content/Styles/uploadify.css" rel="stylesheet" type="text/css" />
在页面上放一个最普通的file控件(其中checkImport是我自己写的一个验证方法,当没有选择上传文件的时候警告):
<div> <p><input id="fileInput1" name="fileInput1" type="file"/></p> <p style="margin-top:5px;font-size:14px;font-weight:bold;"> <a href="javascript:if(checkImport()){$('#fileInput1').uploadifyUpload();}">导入文件</a></p> <p style="margin-top:5px;font-size:14px;font-weight:bold;"><span id="result"></span></p> </div>
然后就可以加入如下js,其中script就是请求服务器的一个处理地址,在webform中通常是指向一个aspx或者ashx文件,在MVC中则是请求一个action,比如这里就是请求ExcelController的Import方法(我的路由是"Admin/{controller}/{action}/{id}"):
$(function() { //上传 $('#fileInput1').uploadify({ 'uploader': '/Content/Images/uploadify.swf', 'script': '/Admin/Excel/Import', 'folder': '/UploadFiles', 'cancelImg': '/Content/Images/cancel.png', 'fileExt': '*.xls', 'fileDesc': '*.xls', 'sizeLimit': 1024 * 1024 * 4, //4M 'multi': false, 'onComplete': fun }); }); function fun(event, queueID, fileObj, response, data) { if (response != "") { showInfo("成功上传"+response, true); //showInfo方法设置上传结果 } else { showInfo("文件上传出错!", false); } }
在对应的ExcelController中就可以这么写:
[AcceptVerbs(HttpVerbs.Post)] public ContentResult Import(HttpPostedFileBase FileData, string folder) { string result = ""; if (null != FileData) { try { result = Path.GetFileName(FileData.FileName);//获得文件名 string ext = Path.GetExtension(FileData.FileName);//获得文件扩展名 string saveName = "uploadfile" + ext;//实际保存文件名 saveFile(FileData, folder, saveName);//保存文件 } catch { result = ""; } } return Content(result); } [NonAction] private void saveFile(HttpPostedFileBase postedFile, string filepath, string saveName) { string phyPath = Request.MapPath("~" + filepath + "/"); if (!Directory.Exists(phyPath)) { Directory.CreateDirectory(phyPath); } try { postedFile.SaveAs(phyPath + saveName); } catch (Exception e) { throw new ApplicationException(e.Message); } }
注意两个参数FileData和folder都是固定名称的,并且FileData的参数类型是HttpPostedFileBase而不是HttpPostedFile(我刚开始就是在这里纠结很久,总是取不到文件),关于为什么要使用HttpPostedFileBase,我在网上找到这样一段话,看来是由于单元测试的原因吧。。。
成功上传文件后的效果如下: