C#文件上传与下载

C#文件上传与下载

开发工具与关键技术:VS     MVC、SQL
撰写时间:2019/5/14

在一个系统中,用户需要上传一份文件到服务器中,但是编程的程序代码中不允许提交特殊字符,程序默认为危险字符,故需要提交这种字符的话,需要取消程序验证。[ValidateInput(false)]取消危险字符的验证 如 “<> %KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲”等等 ;为了安全起见,正常的…/等敏感字符的(有点类似脚本注入),如果你有必要提交这些东西的话,就需要加上ValidateInput标签,比如要录入HTML内容的时候,富文本编辑的时候。

上传文件到项目中,但是这并不代表文件就是直接保存到数据库中了,不增加数据库的存储压力,这些文件一般是存放于项目的文件夹中,在代码中已经指明了文件上传到那个文件夹中。因为上传文件之后可以下载这个文件,所以在数据库只是保存下载这个文件的路径
C#文件上传与下载
在数据库记录的是一个路径,这个路径表示是文件下载的路径。在数据库保存的路径结果如下截图:
C#文件上传与下载
<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/*"表示打开的文件必须是图片类型的文件,其打开文件选择框的效果如下截图:
C#文件上传与下载
上传文件以HttpPostedFileBase attachmenFile 作为上传文件方法的传入参数,上传的文件属于附件不能太大,所以上传文件之前需要对文件的大小进行判断,用try{}catch(){}捕足错误;

1、 判断文件的大小attachmentFile.ContentLength
是否大于0,大于0说明用户已选择到文件,上传的文件就不为空了;
2、 判断文件是否是大于20M,大于20M的文件不能上传,要提醒用户所上传的文件过大,请重新选择上传文件。
C#文件上传与下载

    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提交方式,发送数据。方法如下截图:
C#文件上传与下载
C#文件上传与下载
附件的下载,根据上传时,把文件下载的路径已经保存数据库中,并且是保存在a标签中,故要下载附件的时候,直接点击附件下载即可根据附件是否存在文件中的情况,不在文件夹中就不能下载。下面是下载附件的方法截图:
C#文件上传与下载