一、需求
我們在用.net開發網站時,經常會用到圖片上傳,可以說是每個網站必備的,大到門戶網站,電商網站,政務系統,OA系統,小到企業網站,個人網站,博客網站,導航網站等等,都有用到圖片上傳,那麼在客戶端瀏覽器中上傳圖片,不可避免有些不法分子將病毒僞裝圖片文件,然後上傳到我們的網站服務器,這樣造成網站崩潰。爲了解決這個問題,我們在程序中先過濾,就有了接下來的文章。
二、主要代碼
1、MVC中
我們就來上傳一個頭像,在MVC中怎麼實現文件上傳,請查看我的文章:【MVC系列】ASP.NET MVC中如何實現文件上傳 FileUpLoad
/// <summary>
/// 上傳頭像
/// </summary>
/// <param name="userId">用戶編號</param>
/// <returns>Json(-1表示系統異常,-2表示文件不合法)</returns>
[HttpPost]
public JsonResult Upload(string userId)
{
//上傳頭像的路徑
string folderPath = "/upload/avatar/";
//判斷路徑是否存在
if (!Directory.Exists(folderPath))
Directory.CreateDirectory(folderPath);//創建文件路徑
HttpPostedFileBase uploadFile = Request.Files["avatars"];
if (uploadFile != null)
{
string oriFileName = uploadFile.FileName;//原始文件名
string fileName = userId + "_" + oriFileName;//文件名的格式:用戶Id+文件名
uploadFile.SaveAs(Server.MapPath(folderPath + fileName));//保存到服務器
FileStream fs = new FileStream(Server.MapPath(folderPath + fileName), FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
string fileClass;
byte buffer;
byte[] b = new byte[2];
buffer = reader.ReadByte();
b[0] = buffer;
fileClass = buffer.ToString();
buffer = reader.ReadByte();
b[1] = buffer;
fileClass += buffer.ToString();
reader.Close();
fs.Close();
if (fileClass == "255216" || fileClass == "7173" || fileClass == "6677" || fileClass == "13780")
{
//255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar
//Response.Write("圖片可用");
//保存到數據庫中
}
else
{
//Response.Write("圖片非法");
FileInfo f = new FileInfo(Server.MapPath(folderPath + fileName));
f.Delete(); //刪除文件
return Json(-2, JsonRequestBehavior.AllowGet);
}
return Json(Server.HtmlEncode(folderPath + fileName), JsonRequestBehavior.AllowGet);
}
return Json(-1, JsonRequestBehavior.AllowGet);
}
2、WebForm中
public void UploadFile() {
try {
HttpPostedFile postfile = Request.Files["file"];
string savepath = Server.MapPath("/upload/avatar/" + postfile.FileName);
postfile.SaveAs(savepath);
FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
string fileClass;
byte buffer;
byte[] b = new byte[2];
buffer = reader.ReadByte();
b[0] = buffer;
fileClass = buffer.ToString();
buffer = reader.ReadByte();
b[1] = buffer;
fileClass += buffer.ToString();
reader.Close();
fs.Close();
if (fileClass == "255216" || fileClass == "7173" || fileClass == "6677" || fileClass == "13780") {
//255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar
//Response.Write("圖片可用");
//保存到數據庫中
}
else {
//Response.Write("圖片非法");
File.Delete(savepath); //刪除文件
return;
}
}
catch (Exception) { //Response.Write("圖片非法!");
return;
throw;
}
}
3.用image對象判斷是否爲圖片
///
/// 判斷文件是否爲圖片
///
/// 文件的完整路徑
/// 返回結果
public Boolean IsImage(string path)
{
try
{
System.Drawing.Image img = System.Drawing.Image.FromFile(path);
return true;
}
catch (Exception e)
{
return false;
}
}
三、總結
當然,這個只是防範病毒的一個很小的舉措,技術不深奧,當然我這裏寫的過濾有個很大的缺陷,是先把文件上傳上服務器,然後再檢測,這樣也不安全,可以在上傳之前先檢測,大家自己去實現哈。當然,上傳文件要保證服務器的安全還有很多需要做的,比如在服務器中安裝殺毒軟件定時監測新增文件。還有硬件防火牆很多,在這裏不再闡述。
在本章中如果在MVC中文件上傳無從下手的同學,可以學習到文件上傳,源碼中採用swfupload上傳,它可以支持多文件上傳。具體實現請在文章末尾下載源代碼。給大家佈置一個作業,作進一步思考,怎麼實現跨域或分佈式上傳文件。(作業的需求:網站文件服務器與Web服務器分離,用戶上傳文件的時候,我們把文件存取到文件服務器中,如果文件服務器磁盤已滿,該作怎麼處理?當然還有如果多用戶同時上傳文件,對磁盤寫入,我們服務器配置無法滿足現有的併發寫入,我們需要考慮多文件服務器,多文件服務器,那麼我們在上傳文件又該做怎麼處理呢?這裏就涉及負載均衡和分佈式)