博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
文件上传的几个 - 示例
阅读量:6159 次
发布时间:2019-06-21

本文共 20288 字,大约阅读时间需要 67 分钟。

本篇将要和朋友们分享的是几个上传文件的例子和逻辑步奏及自定义个简单的js上传插件我取名为;近来在讨论组中很有几个朋友咨询上传文件的代码和怎么下载上传的文件,所以写了此篇文章,希望能为朋友们解答一些疑惑或能带来帮助,也谢谢各位多多支持点赞。

 

以上是个人的看法,下面来正式分享今天的文章吧:

. 使用iis发布保存上传文件的文件夹

. 示例A - 普通表单上传文件,Request.Files获取上传文件

. 示例B - 普通表单上传文件,HttpPostedFileBase获取上传文件

. 示例C - ajax+FormData上传文件,Request.Files获取上传文件

. 示例D - 自定义上传插件,Request.Files获取上传文件并提交表单内容

 

下面一步一个脚印的来分享:

. 使用iis发布保存上传文件的文件夹

首先,因为我们上传文件后,需要查看或者下载这个文件,通常分为两种形式;一种把上传的文件上传到程序的根目录中的某个文件夹中,这种就可以直接通过站点的虚拟路径来访问,这种其实也是使用了iis发布的;第二种是通过程序上传到服务器的某个磁盘中,这种路径通常就不在上传程序站点的目录下,因为想让用户通过其他的url地址访问下载文件,iis发布只是其中一种;其实用iss发布保存上传文件的文件夹和发布程序一样差不多;

我们随便找个某磁盘下面的文件夹当做保存上传文件的文件夹,我这里磁盘路径是:D:\D\TTest这个TTest文件夹,然后放几张测试的图片,并复制这个路径,在iis中创建一个站点物理路径指向刚才的复制的路径,端口我这里是1010,我这里没有域名只有用本机的ip代替,这里默认是localhost,配置好后,查看高级设置如:

然后点击"测试文件地址"这个站点-》内容视图 能看到如图的效果

然后,鼠标指上去右键其中某一张图片-》浏览 这样浏览器马上就能看到如图所示的效果:

这样就完成了iis发布文件夹,当然通过http访问图片只是多种方式的一种;有些后缀的文件可能访问不了,需要手动在iis中增加mime类型:

 

. 示例A - 普通表单上传文件,Request.Files获取上传文件

首先,我们来看下html主要代码:

1 
2
示例A - 普通表单上传文件,Request.Files获取上传文件3
4
5
6
7

看是简单简单及简短的代码,其实是上传的重要部分必不可少的,下面就来简单总结下:

. form元素的action属性:表单提交地址,这里是文件上传的接口地址

. 必须采用method="post"提交方式

. 表单提交数据的格式是enctype="multipart/form-data"

. type="file"元素必须要有属性name,这里例子是name="fileA"

. type="file"元素的multiple属性可选,意思是可以选择多个上传文件不用再增加file标签元素来支持上传多个文件了,这个在近几年移动端火热的时候几乎所有最新版本浏览器都支持

再来,我们一起看下后端怎么接受表单提交过来的文件信息,先来看代码:

1 [HttpPost] 2         public ActionResult A() 3         { 4             var sbLog = new StringBuilder(string.Empty); 5  6             var fileCount = Request.Files.Count; 7             //访问上传文件地址 8             var path = @"http://localhost:1010/{0}"; 9             //保存文件地址10             var uploadPath = @"D:\D\TTest";11             sbLog.AppendFormat("上传文件目录:{0}
", uploadPath);12 sbLog.AppendFormat("上传文件量:{0}
", fileCount);13 for (int i = 0; i < fileCount; i++)14 {15 var file = Request.Files[i];16 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; }17 18 var fileName = file.FileName;19 var fileNewName = DateTime.Now.Ticks + fileName;20 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName));21 file.SaveAs(Path.Combine(uploadPath, fileNewName));22 }23 return Content(sbLog.ToString());24 }

这段代码的总要点列举如下:

. Request.Files:用来获取上传的文件,所有上传文件都以此来获取,什么文件名称也包含在列表中

. path变量:就是咋们在前面配置的iis发布文件夹的url路径,只需要传递上传的文件的名称就可以访问

. uploadPath:保存文件地址

. 通过for循环获取上传上来的文件信息和通过file.SaveAs保存到uploadPath指定的文件夹中去

. Path.Combine方法把传递进来的参数拼接长一个磁盘路径如第一个参数值是D:/第二个参数是test.png那么这个方法返回的结果是D:/test.png

最终我这个Action返回的是ContentResult,因为我想在页面输入一些信息好截图哈哈,好了咋们通过复制上面的代码运行起来点"提交"按钮得到的效果如图:

文件夹中选择上的两张图片,就是我们页面上传上来的,通过点击Action返回给页面的下载地址,我们可以在浏览器中浏览图片;好这个上传图片,浏览图片的过程描述大概就是这样,朋友们有收获一些么

 

. 示例B - 普通表单上传文件,HttpPostedFileBase获取上传文件

经过示例A描述的上传,下载图片流程应该都很清楚了,这个小节主要是换了一种获取上传文件信息的方式,我们通过HttpPostedFileBase获取(其实示例ARequest.Files的最底层就是这个),因为可能上传多个文件所以使用了IEnumerable<HttpPostedFileBase>类型来当做Action的参数,试图部分我们使用HtmlHelper的BeginForm方法来生成form标签,具体代码如:

1  
2
示例B - 普通表单上传文件,HttpPostedFileBase获取上传文件3 @using (Html.BeginForm("B", "Error", FormMethod.Post, new { enctype = "multipart/form-data" }))4 {5
6
7 }8

这里使用@html.BeginForm写法主要是满足使用mvc的同学,简单说下这里使用的BeginForm参数:BeginForm(Action,Controller,表单提交方式,增加form属性enctype);好再来看下Controller的代码如:

1 [HttpPost] 2         public ActionResult B(IEnumerable
files) 3 { 4 var sbLog = new StringBuilder(string.Empty); 5 6 var fileCount = files == null ? 0 : files.Count(); 7 //访问上传文件地址 8 var path = @"http://localhost:1010/{0}"; 9 //保存文件地址10 var uploadPath = @"D:\D\TTest";11 sbLog.AppendFormat("上传文件目录:{0}
", uploadPath);12 sbLog.AppendFormat("上传文件量:{0}
", fileCount);13 var i = 0;14 foreach (var file in files)15 {16 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; }17 18 var fileName = file.FileName;19 var fileNewName = DateTime.Now.Ticks + fileName;20 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:
{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName));21 file.SaveAs(Path.Combine(uploadPath, fileNewName));22 }23 return Content(sbLog.ToString());24 }

上面的代码与示例A对比一下,可以看出处理方式几乎是一模一样呢,那这里就没什么说的了,主要是展示下两种获取file文件信息的方式,但下面的将与众不同

 

. 示例C - ajax+FormData上传文件,Request.Files获取上传文件

首先,来了解下FormData这个近几年才被几乎所有浏览器支持的js对象,它的构造函数:new FormData (form? : HTMLFormElement),后面的?号和C#参数差不多表示参数非必须,FormData的最大优点就是可以异步上传一个二进制文件,好吧这个神奇了;继续来将示例C,通常我们提交一般的文字信息直接通过jquery的ajax,post,get等几个方法就能传递到后台,这些直接传参方式无法吧file信息传递给后台,但用到FormData我们就可以用ajax把file文件信息传递给后台,这样我们也可以有更好的无刷新效果的上传文件了,先来看下前端html代码和js代码:

示例C - ajax+FormData上传文件,Request.Files获取上传文件 @using (Html.BeginForm("C", "Error", FormMethod.Post, new { enctype = "multipart/form-data", @id = "form_c" })) {
账号:
密码:
文件:
}

上面的html代码与示例B的格式差不多,只是增加了两个input元素方便我们来测试;重点在js代码中,由上面介绍可以看到FormData的构造只能是HTMLFormElement,所以我们通过document.getElementById("form_c")来获取这个表单的对象传递给它;

然后,我们用普通的$.ajax提交FormData对象到后台进行上传,至于后台我们参照示例A的方式来获取文件信息,不用做什么特殊额处理,只是我们返回的信息是Json数据,代码如:

1 [HttpPost] 2         public JsonResult C() 3         { 4             Thread.Sleep(1000 * 5); 5             var response = new MoResponse(); 6             var sbLog = new StringBuilder("开始处理..."); 7             try 8             { 9 10                 sbLog.AppendFormat("账号:{0}
", Request.Params["userName"]);11 sbLog.AppendFormat("密码:{0}
", Request.Params["userPwd"]);12 13 var fileCount = Request.Files.Count;14 //访问上传文件地址15 var path = @"http://localhost:1010/{0}";16 //保存文件地址17 var uploadPath = @"D:\D\TTest";18 sbLog.AppendFormat("上传文件目录:{0}
", uploadPath);19 sbLog.AppendFormat("上传文件量:{0}
", fileCount);20 for (int i = 0; i < fileCount; i++)21 {22 var file = Request.Files[i];23 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; }24 25 var fileName = file.FileName;26 var fileNewName = DateTime.Now.Ticks + fileName;27 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName));28 file.SaveAs(Path.Combine(uploadPath, fileNewName));29 response.Status = 1;30 }31 }32 catch (Exception ex)33 {34 sbLog.AppendFormat("异常信息:{0}", ex.Message);35 }36 finally37 {38 response.Data = sbLog.ToString();39 }40 return Json(response);41 }
View Code

下面我们看一下添加"提交"按钮执行后返回的效果,可以看出提交后没有跳转到action指向的路由,这样用户体验就好多了:

. 示例D - 自定义上传插件,Request.Files获取上传文件并提交表单内容

首先,我发个插件下载地址,只需要在试图或者html页面引用jquery-1.10.2.min.js库和这个插件,我们就可以这样使用:

1 

使用插件的地方和js关键点已经通过代码注释备注好了,朋友们可仔细阅读下,这里要将的是插件上传文件和提交表单数据的逻辑;我们分析下:

. form表单中通常有其他的属性数据

. form表单的提交数据的后台地址可能和上传文件的后台地址不一样

. 需要单独上传文件后,返回是否上传成功,再提交form表单的其他数据到后台

由上面几点插件的参数定义为:

1  var defOption = {2 3         url: "http://www.cnblogs.com/wangrudong003/",   //上传路由地址,注:1.目前通过该地址上传文件成功后,返回的信息是text/plain  2.跨域暂未考虑4         fileEleName: "fileName",                        //上传input file控件的唯一名称5         uid: new Date().getTime(),                      //防重复6         backFun: function () { }                         //回调函数7     };

这个自定义插件原理和几个重点是:

. 自动创建一个iframe(用来做无刷新体验),iframe里面创建一个form表单,form表单里面只包含要上传的文件file对象,最终把iframe加入到视图页面中

. 通过iframe.load()方法来获取上传文件后返回到contentWindow.document.body中的信息,并且执行自定义回调函数,把参数传递给自定义方法方便使用者自由的控制体验效果

. 创建的form表单里面只能使用页面选择文件上传的文件file对象,使用jquery的clone()函数无法获取到选择的文件对象(这是一个悲剧),所以我这个使用append把用户使用的那个file对象直接包含到创建的form中去,然后在创建一个初始化的file元素对象到原始的视图中去代替被移除掉的file元素,代码如(这个还真花了我2个小时的时间尝试):

1             //清空自定义form多余的file元素2             form.html("");3             var files = $("input[name='" + defOption.fileEleName + "']");4             //复制上传控件对象5             var filesClone = files.clone(true);6             filesClone.insertAfter(files);7             form.append(files);

. 使用该插件提交原始表单数据的顺序是:用户点击页面的保存按钮-》通过插件创建的上传文件的form表单,提交上传文件-》上传文件返回成功与否的信息-》收到上传成功新文件名称信息,创建个hidden保存新文件名称到原始form中去-》再真实提交原始form表单的其他数据

下面来看下效果图:

示例D的后台代码分为两部分:1.上传文件的Action 2.真实获取表单form参数的Action,代码如:

1  ///  2         /// 保存form提交的表单数据 3         ///  4         /// 
5 [HttpPost] 6 public JsonResult D() 7 { 8 var response = new MoResponse(); 9 var sbLog = new StringBuilder(string.Empty);10 try11 {12 //访问上传文件地址13 var path = @"http://localhost:1010/{0}";14 sbLog.AppendFormat("账号:{0}
", Request.Params["userName"]);15 sbLog.AppendFormat("密码:{0}
", Request.Params["userPwd"]);16 foreach (var item in Request.Params["hidFileNames"].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))17 {18 sbLog.AppendFormat("文件新名称:{0};下载地址:{0}
", item, string.Format(path, item));19 }20 response.Status = 1;21 }22 catch (Exception ex)23 {24 sbLog.AppendFormat("异常信息:{0}", ex.Message);25 }26 finally27 {28 response.Data = sbLog.ToString();29 }30 return Json(response);31 }32 33 34 /// 35 /// 获取上传文件信息36 /// 37 ///
38 [HttpPost]39 public ContentResult D_A()40 {41 var response = new MoResponse();42 response.Data = "上传失败";43 try44 {45 Thread.Sleep(1000 * 3);46 var fileCount = Request.Files.Count;47 //保存文件地址48 var uploadPath = @"D:\D\TTest";49 var fileNames = string.Empty;50 for (int i = 0; i < fileCount; i++)51 {52 var file = Request.Files[i];53 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; }54 55 var fileName = file.FileName;56 var fileNewName = DateTime.Now.Ticks + fileName;57 file.SaveAs(Path.Combine(uploadPath, fileNewName));58 fileNames += fileNewName + "|";59 }60 if (!string.IsNullOrEmpty(fileNames))61 {62 63 response.Status = 1;64 response.Data = fileNames.TrimEnd('|');65 }66 }67 catch (Exception ex)68 {69 response.Data = ex.Message;70 }71 return Content(JsonConvert.SerializeObject(response));72 }

好了插件需要讲解的就这么多,不知不觉有只剩我一个人了,该回家了,下面给出整体的代码,插件代码请使用连接获取:

插件下载地址:

Controller代码:

1 public class ErrorController : Controller  2     {  3         //  4         // GET: /Error/  5         public ActionResult Index()  6         {  7   8             return View();  9         } 10  11         [HttpPost] 12         public ActionResult A() 13         { 14             var sbLog = new StringBuilder(string.Empty); 15  16             var fileCount = Request.Files.Count; 17             //访问上传文件地址 18             var path = @"http://localhost:1010/{0}"; 19             //保存文件地址 20             var uploadPath = @"D:\D\TTest"; 21             sbLog.AppendFormat("上传文件目录:{0}
", uploadPath); 22 sbLog.AppendFormat("上传文件量:{0}
", fileCount); 23 for (int i = 0; i < fileCount; i++) 24 { 25 var file = Request.Files[i]; 26 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; } 27 28 var fileName = file.FileName; 29 var fileNewName = DateTime.Now.Ticks + fileName; 30 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName)); 31 file.SaveAs(Path.Combine(uploadPath, fileNewName)); 32 } 33 return Content(sbLog.ToString()); 34 } 35 36 [HttpPost] 37 public ActionResult B(IEnumerable
files) 38 { 39 var sbLog = new StringBuilder(string.Empty); 40 41 var fileCount = files == null ? 0 : files.Count(); 42 //访问上传文件地址 43 var path = @"http://localhost:1010/{0}"; 44 //保存文件地址 45 var uploadPath = @"D:\D\TTest"; 46 sbLog.AppendFormat("上传文件目录:{0}
", uploadPath); 47 sbLog.AppendFormat("上传文件量:{0}
", fileCount); 48 var i = 0; 49 foreach (var file in files) 50 { 51 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; } 52 53 var fileName = file.FileName; 54 var fileNewName = DateTime.Now.Ticks + fileName; 55 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:
{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName)); 56 file.SaveAs(Path.Combine(uploadPath, fileNewName)); 57 } 58 return Content(sbLog.ToString()); 59 } 60 61 [HttpPost] 62 public JsonResult C() 63 { 64 Thread.Sleep(1000 * 5); 65 var response = new MoResponse(); 66 var sbLog = new StringBuilder("开始处理..."); 67 try 68 { 69 70 sbLog.AppendFormat("账号:{0}
", Request.Params["userName"]); 71 sbLog.AppendFormat("密码:{0}
", Request.Params["userPwd"]); 72 73 var fileCount = Request.Files.Count; 74 //访问上传文件地址 75 var path = @"http://localhost:1010/{0}"; 76 //保存文件地址 77 var uploadPath = @"D:\D\TTest"; 78 sbLog.AppendFormat("上传文件目录:{0}
", uploadPath); 79 sbLog.AppendFormat("上传文件量:{0}
", fileCount); 80 for (int i = 0; i < fileCount; i++) 81 { 82 var file = Request.Files[i]; 83 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; } 84 85 var fileName = file.FileName; 86 var fileNewName = DateTime.Now.Ticks + fileName; 87 sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:
{2}
", i + 1, fileName, fileNewName, string.Format(path, fileNewName)); 88 file.SaveAs(Path.Combine(uploadPath, fileNewName)); 89 response.Status = 1; 90 } 91 } 92 catch (Exception ex) 93 { 94 sbLog.AppendFormat("异常信息:{0}", ex.Message); 95 } 96 finally 97 { 98 response.Data = sbLog.ToString(); 99 }100 return Json(response);101 }102 103 ///
104 /// 保存form提交的表单数据105 /// 106 ///
107 [HttpPost]108 public JsonResult D()109 {110 var response = new MoResponse();111 var sbLog = new StringBuilder(string.Empty);112 try113 {114 //访问上传文件地址115 var path = @"http://localhost:1010/{0}";116 sbLog.AppendFormat("账号:{0}
", Request.Params["userName"]);117 sbLog.AppendFormat("密码:{0}
", Request.Params["userPwd"]);118 foreach (var item in Request.Params["hidFileNames"].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))119 {120 sbLog.AppendFormat("文件新名称:{0};下载地址:
{0}
", item, string.Format(path, item));121 }122 response.Status = 1;123 }124 catch (Exception ex)125 {126 sbLog.AppendFormat("异常信息:{0}", ex.Message);127 }128 finally129 {130 response.Data = sbLog.ToString();131 }132 return Json(response);133 }134 135 136 ///
137 /// 获取上传文件信息138 /// 139 ///
140 [HttpPost]141 public ContentResult D_A()142 {143 var response = new MoResponse();144 response.Data = "上传失败";145 try146 {147 Thread.Sleep(1000 * 3);148 var fileCount = Request.Files.Count;149 //保存文件地址150 var uploadPath = @"D:\D\TTest";151 var fileNames = string.Empty;152 for (int i = 0; i < fileCount; i++)153 {154 var file = Request.Files[i];155 if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; }156 157 var fileName = file.FileName;158 var fileNewName = DateTime.Now.Ticks + fileName;159 file.SaveAs(Path.Combine(uploadPath, fileNewName));160 fileNames += fileNewName + "|";161 }162 if (!string.IsNullOrEmpty(fileNames))163 {164 165 response.Status = 1;166 response.Data = fileNames.TrimEnd('|');167 }168 }169 catch (Exception ex)170 {171 response.Data = ex.Message;172 }173 return Content(JsonConvert.SerializeObject(response));174 }175 }176 177 public class MoResponse178 {179 180 public object Data { get; set; }181 182 ///
183 /// 0:失败 1:成功184 /// 185 public int Status { get; set; }186 }
View Code

View代码:

1 @{  2     ViewBag.Title = "上传 - 示例";  3 }  4   5   6   7       8     
9 10 11 12
13
14
示例A - 普通表单上传文件,Request.Files获取上传文件 15
16
17
18
19
20 21 22
23
示例B - 普通表单上传文件,HttpPostedFileBase获取上传文件 24 @using (Html.BeginForm("B", "Error", FormMethod.Post, new { enctype = "multipart/form-data" })) 25 { 26
27
28 } 29
30 31
32
示例C - ajax+FormData上传文件,Request.Files获取上传文件 33 @using (Html.BeginForm("C", "Error", FormMethod.Post, new { enctype = "multipart/form-data", @id = "form_c" })) 34 { 35
账号:
36
密码:
37
文件:
38
39
40 } 41
42 43
44
示例D - 自定义上传插件,Request.Files获取上传文件并提交表单内容 45 @using (Html.BeginForm("D", "Error", FormMethod.Post, new { enctype = "multipart/form-data", @id = "form_d" })) 46 { 47
账号:
48
密码:
49
文件:
50
51
52 } 53
54
55 56 57 58 59
View Code
git地址:     nuget发布包:
img_b0f7f3094651b5685efcc535a055b326.gif
你可能感兴趣的文章
Red Hat 安装源包出错 Package xxx.rpm is not signed
查看>>
编译安装mysql-5.6.16.tar.gz
查看>>
活在当下
查看>>
每天进步一点----- MediaPlayer
查看>>
PowerDesigner中CDM和PDM如何定义外键关系
查看>>
跨域-学习笔记
查看>>
the assignment of reading paper
查看>>
android apk 逆向中常用工具一览
查看>>
MyEclipse 报错 Errors running builder 'JavaScript Validator' on project......
查看>>
Skip List——跳表,一个高效的索引技术
查看>>
Yii2单元测试初探
查看>>
五、字典
查看>>
前端js之JavaScript
查看>>
Log4J日志配置详解
查看>>
实验7 BindService模拟通信
查看>>
scanf
查看>>
Socket编程注意接收缓冲区大小
查看>>
SpringMVC初写(五)拦截器
查看>>
检测oracle数据库坏块的方法
查看>>
SQL server 安装教程
查看>>