ASP.NET MVC之文件上传【二】

时间:2022-09-26 17:17:59

前言

上一节我们讲了简单的上传以及需要注意的地方,查相关资料时,感觉上传里面涉及到的内容还是比较多,于是就将上传这一块分为几节来处理,同时后续也会讲到关于做上传时遗漏的C#应该注意的地方,及时进行查漏补缺,尽量将这一块完善起来。

引入

上一节我们讲到了上传这一块,在评论中有园友提出未涉及到大文件的上传这一块,思前想后还是来试着做做,毕竟之前没怎么去仔细考虑过这个问题,尤其还可以联系实际开发中创建文件夹等一系列问题,同时关于上传在网上随便找找都充斥着大量的组件,我们何必再去造*,我需要做的是只是对基础的回顾以及进一步深入以及在做的过程中发现一些细节性的问题并解决就足矣,不喜勿喷。

深入上传

再次声明对于上传可以显示上传进度之类我们不去做过多探讨,有这样的组件,自行去找,我们只需实现比较核心的这一块即可。

我们可以想象这一样一个场景:比如在博客园中,每个博客者都可以上传文件如图片、脚本之类,我们可以通过园友名称来创建每个园友上传的文件,接下来我们来实现这样的一个场景。

既然是对应博客的名称创建文件,也就是需要对应的博客这样的一个类。如下:

ASP.NET MVC之文件上传【二】
    public class BlogSample
{
public string UserName { get; set; } public string Id { get; set; }
}
ASP.NET MVC之文件上传【二】

我们通过博客名称来创建文件夹并在该文件夹下以唯一的Id来创建子文件夹,在该Id文件夹下的附件( atttachment )中存储上传的文件。接下来我们需要梳理整个上传文件的过程。难道就把要上传的文件直接到上传到对应的文件夹吗,这么做显然不是最优的,当有上传中断时则在文件夹创建的文件不是完整的则是垃圾文件,而我们直接先创建一个临时文件,即使上传失败我们可以定期清理临时文件也就是垃圾文件,若未中断,上传完毕时则将临时文件移动到我们对应的文件夹中。通过我们实际下载文件时很明显看的出也是这么做的。接下来我们开始进行实现。

(1)我们给出一个关于上传的 UploadManager 静态类,我们可以写死上传的文件夹名称或者通过配置文件自定义上传文件夹名称。

ASP.NET MVC之文件上传【二】
        static UploadManager()
{
//从配置文件中获取上传文件夹
if (String.IsNullOrWhiteSpace(WebConfigurationManager.AppSettings["UploadFolder"]))
UploadFolderRelativePath = @"~/upload";
else
UploadFolderRelativePath = WebConfigurationManager.AppSettings["UploadFolder"]; UploadFolderPhysicalPath = HostingEnvironment.MapPath(UploadFolderRelativePath); if (!Directory.Exists(UploadFolderPhysicalPath))
Directory.CreateDirectory(UploadFolderPhysicalPath);
}
ASP.NET MVC之文件上传【二】

上述已经表明可以自定义上传文件夹在配置文件中(给出上传虚拟路径),例如如下:

  <!--<add key="UploadFolder" value="~/UploadFile/">-->

(2)保存文件的核心方法

ASP.NET MVC之文件上传【二】
        [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
public static bool SaveFile(Stream stream, string fileName, string userName, string guid)
{
string tempPath = string.Empty, targetPath = string.Empty; try
{
string tempFileName = GetTempFilePath(fileName); if (userName != null)
{
var contentType = userName;
var contentId = guid; tempPath = GetTempFilePath(tempFileName);
targetPath = GetTargetFilePath(fileName, contentType, contentId, string.Empty, FilesSubdir); //若上传文件夹中子文件夹未存在则创建
var file = new FileInfo(targetPath);
if (file.Directory != null && !file.Directory.Exists)
file.Directory.Create(); using (FileStream fs = File.Open(tempPath, FileMode.Append))
{
if (stream.Length > 0)
{
SaveFile(stream, fs);
}
fs.Close();
}
//上传完毕将临时文件移动到目标文件
File.Move(tempPath, targetPath);
}
}
catch (Exception)
{
// 若上传出错,则删除上传到文件夹文件
if (File.Exists(targetPath))
File.Delete(targetPath); // 删除临时文件
if (File.Exists(tempPath))
File.Delete(tempPath); return false;
}
finally
{
// 删除临时文件
if (File.Exists(tempPath))
File.Delete(tempPath);
}
return true;
}
ASP.NET MVC之文件上传【二】

(3)循环读取流到文件流中

ASP.NET MVC之文件上传【二】
         /// <summary>
/// 循环读取流到文件流中
/// </summary>
/// <param name="stream"></param>
/// <param name="fs"></param>
public static void SaveFile(Stream stream, FileStream fs)
{
var buffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
fs.Write(buffer, 0, bytesRead);
}
}
ASP.NET MVC之文件上传【二】

(4)开始写入测试数据,进行调用方法:

ASP.NET MVC之文件上传【二】
            var testSample = new BlogSample() { UserName = "xpy0928", Id = Guid.NewGuid().ToString("N") };
if (ModelState.IsValid)
{
var fileName = bModel.BlogPhoto.FileName;
var success = UploadManager.SaveFile(bModel.BlogPhoto.InputStream, fileName, testSample.UserName, testSample.Id);
if (!success)
{
// TODO(your code)
}
//var filePath = Server.MapPath(string.Format("~/{0}", "File"));
//bModel.BlogPhoto.SaveAs(Path.Combine(filePath, fileName));
ModelState.Clear();
}
ASP.NET MVC之文件上传【二】

接下来我们来进行测试,通过上传一个84M的文件来看看效果(稍等片刻,文件有点大)。

ASP.NET MVC之文件上传【二】

不好意思,令我大失所望,和昨天出现的错误不一样,今天出错是:超过最大请求长度。我们接下来再来看看昨天所说,我的IIS为10.0,也就是在IIS 7+上,通过昨天那样设置应该是没问题的,难道和另外一个设置有关吗,我们看看配置文件中的配置。

<httpRuntime targetFramework="4.5"/>

未进行设置,超过其默认设置28.6M就出错了吗,我们再设置为2G看看。

<httpRuntime targetFramework="4.5" executionTimeout="1100"  maxRequestLength="2147483647"/>

ASP.NET MVC之文件上传【二】

好,上传成功也未出现上述错误。

结语

这一节我们讲了一下利用流来进行大文件的处理,不过还是出现了一点小问题,和昨天再一起做一次总结:

(1)在IIS 5和IIS 6中,默认文件上传的最大为4兆,当上传的文件大小超过4兆时,则会得到错误信息,但是我们通过如下来设置文件大小。

<system.web>
<httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

(2)在IIS 7+,默认文件上传的最大为28.6兆,当超过其默认设置大小,同样会得到错误信息,但是我们却可以通过如下来设置文件上传大小(同时也要进行如上设置)。

ASP.NET MVC之文件上传【二】
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
</system.webServer>
ASP.NET MVC之文件上传【二】

关于在配置文件中如何设置文件大小而不出错,总算做了一个最终的总结,有收获,继续Fighting。

ASP.NET MVC之文件上传【二】的更多相关文章

  1. MVC图片上传、浏览、删除 ASP&period;NET MVC之文件上传【一】(八) ASP&period;NET MVC 图片上传到服务器

    MVC图片上传.浏览.删除   1.存储配置信息 在web.config中,添加配置信息节点 <appSettings> <add key="UploadPath&quot ...

  2. Asp&period;net mvc 大文件上传 断点续传

    Asp.net mvc 大文件上传 断点续传 进度条   概述 项目中需要一个上传200M-500M的文件大小的功能,需要断点续传.上传性能稳定.突破asp.net上传限制.一开始看到51CTO上的这 ...

  3. ASP&period;NET MVC之文件上传【二】(九)

    前言 上一节我们讲了简单的上传以及需要注意的地方,查相关资料时,感觉上传里面涉及到的内容还是比较多,于是就将上传这一块分为几节来处理,同时后续也会讲到关于做上传时遗漏的C#应该注意的地方,及时进行查漏 ...

  4. ASP&period;NET MVC之文件上传【一】(八)

    前言 这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public ActionResult ...

  5. ASP&period;NET MVC之文件上传【一】

    前言 这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public ActionResult ...

  6. asp&period;net mvc 多文件上传

    @{ ViewBag.Title = "多文件上传测试"; } <h2>多文件上传测试</h2> <form action="/Demo/I ...

  7. Asp&period;net mvc 大文件上传 断点续传 进度条

    概述 项目中需要一个上传200M-500M的文件大小的功能,需要断点续传.上传性能稳定.突破asp.net上传限制.一开始看到51CTO上的这篇文章,此方法确实很不错,能够稳定的上传大文件,http: ...

  8. 探索Asp&period;net mvc 的文件上传

    (转自:http://www.cnblogs.com/n-pei/archive/2010/10/15/1852635.html) 最近因为TeamVideo需要用到视频和图片上传功能,所以试着Goo ...

  9. 探索Asp&period;net mvc 的文件上传&lpar;由浅入深&rpar;

    代码下载:http://files.cnblogs.com/n-pei/mvcfileupload.zip 最近因为TeamVideo需要用到视频和图片上传功能,所以试着Google了很多资料,和大家 ...

随机推荐

  1. js库

    lanchpad用的js库 http://lesscss.org/ https://github.com/EightMedia/hammer.js/wiki/Getting-Started http: ...

  2. NSNotificationCenter需要注意的几个问题

    NSNotificationCenter是iOS中常用的消息通知机制,不过在使用过程中有几点需要注意的问题. 直接贴Apple 的官方文档吧: A notification center delive ...

  3. 第一个项目--用bootstrap实现美工设计的首页

    主要介绍在首页实现中用到bootstrap实现效果的地方. 实现如下的效果: <li> <div role="group" style="padding ...

  4. R与数据分析旧笔记(十六) 基于密度的方法:DBSCAN

    基于密度的方法:DBSCAN 基于密度的方法:DBSCAN DBSCAN=Density-Based Spatial Clustering of Applications with Noise 本算法 ...

  5. Sql示例说明如何分组后求中间值--【叶子】

    原文:Sql示例说明如何分组后求中间值--[叶子] 这里所谓的分组后求中间值是个什么概念呢? 我举个例子来说明一下: 假设我们现在有下面这样一个表: type        name price -- ...

  6. Enterprise Architect UML 建模之活动图

    EA(Enterprise Architect) UML 建模之活动图   一.活动图的概念作用 活动图本质上是一种流程图,它描述活动的序列,即系统从一个活动到另一个活动的控制流. 活动图的作用:描述 ...

  7. python3&period;5中,import sqlite3 出现 no module named &lowbar;sqlite3的解决方法

    我用的centos7.2,系统自带python2.7. 我自己装了python3.5,但在导入sqlite3这个包的时候出现找不到包的错误. 下面给出解决方法. 第一种: 检查自己有没有安装sqlit ...

  8. LIBS入门

    样品汽化产生*原子,原子电子的激发诱导光辐射产生表征原子的分立光谱,采集和分析光辐射. 光源:1064nm Nd:YAG固态激光器,10ns脉冲,焦点光密度1 GW·cm−2 可见和紫外光源.   ...

  9. springboot 没有跳转到指定页面

    Whitelabel Error Page   解决办法,添加依赖: <dependency> <groupId>org.springframework.boot</gr ...

  10. react native 开发报错

    1:oc对象名是RCTPoctalk 2:js中导入原生方法 3:报错:对象没有定义 出现这样的问题可能是react native 不允许使用“RCT”开头的前缀 4:解决办法:“RCT_EXPORT ...