以前写上传文件时判断文件大小都是用的类似下面的代码:
if (Request.Files.Count > 0 && Request.Files[0].ContentLength > 0 && Request.Files[0].ContentLength <= maxPictureSize)
{}
最近才知道原来这样做之后,其实IIS已经处理了所有浏览器提交过来的数据(Request.Form或者Request.BinaryRead都会导致IIS处理请求数据),也就是说其实文件已经被服务器接收了,这时候再判断文件大小已经是属于事后判断,而正确的判断方式应当如下:
long fileLength = long.Parse(Request.Headers["Content-Length"]);
if(fileLength<maxPictureSize && Request.Files.Count > 0 && Request.Files[0].ContentLength > 0)
{}
这样做虽然在判断文件大小时会有一定的误差,因为这个length还包含了文件之外的其他数据,但基本误差还在可接受范围之内,而这样做的好处是直接避免了文件被真正上传到服务器之后才进行大小判断
这样的做原理就是IIS在处理请求数据时是按照从上往下的顺序执行的,Request.Headers执行跟Request.Form并不关联,也就是说执行了Request.Headers并不会导致IIS对提交的数据进行处理
顺带补充一下文件类型判断规则:
//根据Request.Files[0].ContentType判断并不是很准确,一般情况下它是对的
//但如果你创建个文本文件,然后将它后缀改成jpg,你会发现上传时它的ContentType就是"image/jpeg"或者 "image/pjpeg"
//但实际上它根本就不是jpg图片,所以按照字节判断才更准确
//byte[] bytes = new byte[2];
//读取图片的第一第二个字节到bytes
//判断string.Format("{0}{1}",bytes[0],bytes[1]);
//255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar
再补充一下下载为指定文件名
string fileName = "test.xls";
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "gb2312";
Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);