C#文件上传与下载
C#文件上传与下载
开发工具与关键技术:VS MVC、SQL
撰写时间:2019/5/14
在一个系统中,用户需要上传一份文件到服务器中,但是编程的程序代码中不允许提交特殊字符,程序默认为危险字符,故需要提交这种字符的话,需要取消程序验证。[ValidateInput(false)]取消危险字符的验证 如 “<> %KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲”等等 ;为了安全起见,正常的…/等敏感字符的(有点类似脚本注入),如果你有必要提交这些东西的话,就需要加上ValidateInput标签,比如要录入HTML内容的时候,富文本编辑的时候。
上传文件到项目中,但是这并不代表文件就是直接保存到数据库中了,不增加数据库的存储压力,这些文件一般是存放于项目的文件夹中,在代码中已经指明了文件上传到那个文件夹中。因为上传文件之后可以下载这个文件,所以在数据库只是保存下载这个文件的路径
在数据库记录的是一个路径,这个路径表示是文件下载的路径。在数据库保存的路径结果如下截图:
<a href="/SystemManagement/IssuanceNotice/DownloadAttachment?fileName=3139642019-04-08-20-08-34-6162.jpg"target="_blank">313964.jpg
上传文件时,需要一个按钮触发文件选择框打开;。input标签的type=”file”表示打开的是文件选择框,在input标签添加accept属性值,表示限定文件类型,即打开文件选择框时,它会根据你所限定的文件类型在显示符合类型的文件。例如:accept="image/*"表示打开的文件必须是图片类型的文件,其打开文件选择框的效果如下截图:
上传文件以HttpPostedFileBase attachmenFile 作为上传文件方法的传入参数,上传的文件属于附件不能太大,所以上传文件之前需要对文件的大小进行判断,用try{}catch(){}捕足错误;
1、 判断文件的大小attachmentFile.ContentLength
是否大于0,大于0说明用户已选择到文件,上传的文件就不为空了;
2、 判断文件是否是大于20M,大于20M的文件不能上传,要提醒用户所上传的文件过大,请重新选择上传文件。
if (attachmentFile.ContentLength >(20 * 1024 * 1024))
{
return Json("上传的文件不能大于20M", JsonRequestBehavior.AllowGet);
}
3、 获取Session中的文件夹
List<Files> sessionFiles = new List<Files>();
if (Session["sessionFiles"]!=null)
{
sessionFiles = Session["sessionFiles"] as List<Files>;
}
4、 上传文件并不是上传到数据库,是上传到项目的文件夹,故上传文件时以防上传的路径找不到,先判断这个文件夹是否存在,不存在就需通过代码创建。
if (!Directory.Exists(Server.MapPath("~/Document/Temp/")))
{
Directory.CreateDirectory(Server.MapPath("~/Document/Temp/"));
}
5、 获取文件类型即文件后缀名,再获取文件名不包括文件后缀名;
string fileExtension = System.IO.Path.GetExtension(attachmentFile.FileName); //文件类型
string fileName =System.IO.Path.GetFileNameWithoutExtension(attachmentFile.FileName); //不包含文件扩展名的名称
string oldFileName = attachmentFile.FileName;//原始文件名称
6、 重命名,拼接当前日期时间,以防用户多次上传同一个文件时发生冲突
fileName = fileName + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff") + fileExtension;
7、 保存文件路径,保存文件
string filePath = Server.MapPath("~/Document/Temp/") + fileName; //保存文件的路径
attachmentFile.SaveAs(filePath);//保存文件
8、 根据文件后缀名判断文件的类型
int fileTypeId;
string fileTypeName;
fileExtension = fileExtension.ToLower();//小写转换
if ("(.mp4)|(.avi)|(.flv)|(.rmvb)|(.rm)|(.3gp)|(.mkv)|(.dvd)|(.mpg)|(.mov)".Contains(fileExtension)){
fileTypeId = 1;//视频
fileTypeName = "视频";
}
else if ("(.mp3)|(.wav)|(.cd)|(.ogg)|(.ape)|(.au)".Contains(fileExtension))
{
fileTypeId = 2;//音频
fileTypeName = "音频";
}
else if ("(.txt)|(.text)".Contains(fileExtension))
{
fileTypeId = 3;//文本
fileTypeName = "文本";
}
else if ("(.doc)|(.docx)|(.xsl)|(.xslx)|(.ppt)|(.pptx)".Contains(fileExtension))
{
fileTypeId = 4;//文档
fileTypeName = "文档";
}
else if ("(.gif)|(.bmp)|(.jpeg)|(.png)|(.jpg)".Contains(fileExtension))
{
fileTypeId = 5;//图片
fileTypeName = "图片";
}
else
{
fileTypeId = 7;//其他
fileTypeName = "其他";
}
9、 保存文件路径到数据库
Files myfiles = new Files();//实例化文件表
{//给文件表赋值
FileTypeID = fileTypeId,
FileTypeName = fileTypeName,
FileName = fileName,
FileGuid = Guid.NewGuid().ToString("N"),//全球唯一标识符 e0a953c3ee6040eaa9fae2b667060e09
//<a class="selected" href="/Document/201612290948105951595.pdf" target="_blank">保卫工作简报(2016年第2期).pdf</a>
//拼接文件下载的方法路径
Files = "<a href=\"/SystemManagement/IssuanceNotice/DownloadAttachment?fileName=" + fileName + "\"target=\"_blank\">" + oldFileName + "</a>",
};
10、 Session记录当前上传的附件,以便用户选择上传时,突然不想上传了,可以移除这个附件
if(sessionFiles!=null) {
sessionFiles.Add(myfiles);
//把上传的附件记录到session
Session["sessionFiles"] =sessionFiles;
return Json(true, JsonRequestBehavior.AllowGet);
}
文件上传的方法写好,需要页面的调用;页面请求方法采用原生的XMLHTTPRequest提交请求,通过input标签的改变事件触发上传,所以在input标签去掉value值的时候取消再次上传附件;
if ($("#getAttachmentFile").val() == "" || $('#getAttachmentFile').val() == undefined) {
return;
}
获取选择的文件var files = $("#getAttachmentFile").prop(“files”);,判断长度是否大于0,再判断文件不大于20M在,再创建FormData对象,把文件放入FromData对象,创建一个XMLHTTPRequest对象;发送成功事件、失败事件,上传进度监控,上传的post提交方式,发送数据。方法如下截图:
附件的下载,根据上传时,把文件下载的路径已经保存数据库中,并且是保存在a标签中,故要下载附件的时候,直接点击附件下载即可根据附件是否存在文件中的情况,不在文件夹中就不能下载。下面是下载附件的方法截图: