本组件通过配置XML文件的信息来对上传文件的路径,文件名格式以及文件大小进行限定。
下面是上传文件的主体文件:
引入相应的命名空间:
using System;
using System.Web;
using System.Data;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Configuration;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
创建FileItem类,用于记录上传文件的基本信息:
public class FileItem

{
public string file_size;
public string file_postname;
public string file_sysname;
public string file_orginname;
public string file_path;
}
接下来是上传文件类,上传方法重载两次,public FileItem UploadFile(HtmlInputFile file)方法的上传路径将默认取配置文件的信息,这个将在后面介绍:
public class FileUpload

{
private bool _blnIsSuccess = true;
private string _FileMessage = "";
private ValidationUploadFile validate = new ValidationUploadFile();

public FileUpload()

{

}

public string UploadFileMessage

{
get

{
return this._FileMessage;
}
}

public bool IsSuccess

{
get

{
return this._blnIsSuccess;
}
set

{
this._blnIsSuccess = value;
}
}

public FileItem UploadFile(HtmlInputFile file)

{
if(validate.IsEligible(file))

{
string FileName = GetUniquelyString(); //Get Unique File Name
string FileOrginName = file.PostedFile.FileName.Substring
(file.PostedFile.FileName.LastIndexOf("\\")+1); //Get Original File Name
string postFileName;
string FilePath = HttpContext.Current.Server.MapPath(System.Configuration.ConfigurationSettings.AppSettings["UploadFilePath"]);
string path = FilePath + "\\";
try

{
DirectoryInfo pathdir=new DirectoryInfo(path);
if (!pathdir.Exists)

{
pathdir.Create();
}
int pos = file.PostedFile.FileName.LastIndexOf(".")+1;
postFileName = file.PostedFile.FileName.Substring(pos,file.PostedFile.FileName.Length-pos);
file.PostedFile.SaveAs(path+FileOrginName); //Save specific file into specific directory
}
catch(Exception exec)

{
throw(exec);
}

double unit = 1024;
double size = Math.Round(file.PostedFile.ContentLength/unit,2);
FileItem fileitem=new FileItem();
fileitem.file_size=size.ToString(); //File Size
fileitem.file_postname=postFileName; //File Type(Extended Name)
fileitem.file_sysname=FileName+"."+postFileName; //System Name
fileitem.file_orginname=FileOrginName; //Original Name
fileitem.file_path=path+FileName+"."+postFileName; //Path
return fileitem;
}
else

{
_FileMessage = validate.ErrorMessage;
message(_FileMessage);
IsSuccess = false;
return null;
}
}

public FileItem UploadFile(HtmlInputFile file,string UploadDir)

{
if(validate.IsEligible(file))

{
string FileName = GetUniquelyString(); //Get Unique File Name
string FileOrginName = file.PostedFile.FileName.Substring
(file.PostedFile.FileName.LastIndexOf("\\")+1); //Get Original File Name
string postFileName;
string FilePath = UploadDir.ToString();
string path = FilePath + "\\";
try

{
DirectoryInfo pathdir=new DirectoryInfo(path);
if (!pathdir.Exists)

{
pathdir.Create();
}

int pos = file.PostedFile.FileName.LastIndexOf(".")+1;
postFileName = file.PostedFile.FileName.Substring(pos,file.PostedFile.FileName.Length-pos);
file.PostedFile.SaveAs(path+FileOrginName); //Save specific file into specific directory
}
catch(Exception exec)

{
throw(exec);
}

double unit = 1024;
double size = Math.Round(file.PostedFile.ContentLength/unit,2);
FileItem fileitem=new FileItem();
fileitem.file_size=size.ToString(); //File Size
fileitem.file_postname=postFileName; //File Type(Extended Name)
fileitem.file_sysname=FileName+"."+postFileName; //System Name
fileitem.file_orginname=FileOrginName; //Original Name
fileitem.file_path=path+FileName+"."+postFileName; //Path
return fileitem;
}
else

{
_FileMessage = validate.ErrorMessage;
message(_FileMessage);
IsSuccess = false;
return null;
}
}

//Generate Unique File Name
public static string GetUniquelyString()

{
const int RANDOM_MAX_VALUE = 1000;
string strTemp,strYear,strMonth,strDay,strHour,strMinute,strSecond,strMillisecond;

DateTime dt =DateTime.Now;
Random rnd = new Random(); //Get an Random String
int rndNumber = rnd.Next(RANDOM_MAX_VALUE);
strYear = dt.Year.ToString ();
strMonth = (dt.Month > 9)? dt.Month.ToString() : "0" + dt.Month.ToString();
strDay = (dt.Day > 9)? dt.Day.ToString() : "0" + dt.Day.ToString();
strHour = (dt.Hour > 9)? dt.Hour.ToString() : "0" + dt.Hour.ToString();
strMinute = (dt.Minute > 9)? dt.Minute.ToString() : "0" + dt.Minute.ToString();
strSecond = (dt.Second > 9)? dt.Second.ToString() : "0" + dt.Second.ToString();
strMillisecond = dt.Millisecond.ToString();

strTemp = strYear + strMonth + strDay +"_"+ strHour + strMinute + strSecond +"_"+ strMillisecond +"_"+ rndNumber.ToString () ;

return strTemp;
}

//Embed javascript code - alert windows
private void message(string msg, string url)

{
System.Web.HttpContext.Current.Response.Write("<script language=javascript>alert('" + msg + "');window.location='" + url + "'</script>");
}

//Embed javascript code - alert windows
private void message(string msg)

{
System.Web.HttpContext.Current.Response.Write("<script language=javascript>alert('" + msg + "');</script>");
}

}
在Upload方法中的validate.IsEligible(file)方法应用Facade模式封装了所有判断上传文件的逻辑,其ValidationUploadFile类将在后面介绍。
另外,上面的message方法将会在上传发生错误时弹出提示框来,所以在前台代码中可以不用判断文件是否上传成功。
ValidationUploadFile类文件的源码如下:
public class ValidationUploadFile

{
private FileSize checkfilesize = new FileSize();
private FileType checkfiletype = new FileType();
private FileExistence isExist = new FileExistence();
private FileName checkfilename = new FileName();
private FileSpecialChar checkchar = new FileSpecialChar();
private UploadFileCfg cfg = new UploadFileCfg();
private string _errormessage = "";

public ValidationUploadFile()

{

}

public string ErrorMessage

{
get

{
return _errormessage;
}
set

{
_errormessage = value;
}
}

//Enscaplation Validation Class --- Facade
public bool IsEligible(HtmlInputFile file)

{
bool blnIsEligible = true;

// Build up Validation Flow
if(!isExist.IsExistFileName(file,cfg))

{
this.ErrorMessage = isExist.ErrorMessage;
blnIsEligible = false;
}
else if(!checkfilename.CheckFileNameLength(file,cfg))

{
this.ErrorMessage = checkfilename.ErrorMessage;
blnIsEligible = false;
}
else if(!checkfiletype.CheckFileType(file,cfg))

{
this.ErrorMessage = checkfiletype.ErrorMessage;
blnIsEligible = false;
}
else if(!checkchar.CheckSpecialChar(file,cfg))

{
this.ErrorMessage = checkchar.ErrorMessage;
blnIsEligible = false;
}
else if(!checkfilesize.CheckFileSize(file,cfg))

{
this.ErrorMessage = checkfilesize.ErrorMessage;
blnIsEligible = false;
}
return blnIsEligible;
}
}
在上面的代码中,我们创建了UploadFileCfg的对象,给类用于读取自定义的XML上的配置信息,然后存放到Hashtable中,以便于查找,如下所示:
同时别忘了引入命名空间
using System;
using System.Xml;
using System.Xml.Xsl;
using System.Collections;
using System.Configuration;
然后读取XML信息:
public class UploadFileCfg

{
public Hashtable CfgInfo = new Hashtable();
public Hashtable Messages = new Hashtable();

public UploadFileCfg()

{
LoadConfigInfo();
LoadMessage();
}

public void LoadConfigInfo()

{
XmlDocument xmlDoc=new XmlDocument();
xmlDoc.Load(HttpContext.Current.Server.MapPath("\\ComponmentTest\\Conf\\UploadFileConfigInfo.xml"));
XmlNodeList nodeList=xmlDoc.SelectSingleNode("FileConfiguration").ChildNodes;
foreach(XmlNode xn in nodeList)

{
if(xn.Name=="ConfigDefinition")

{
XmlElement xe=(XmlElement)xn;
CfgInfoModule model=new CfgInfoModule();
model.ModuleDefId=xe.GetAttribute("CfgDefId");
model.ModuleDefValue=xe.GetAttribute("CfgDefValue");
model.ModelDescription=xe.GetAttribute("CfgDefDescription");
CfgInfo.Add(model.ModuleDefId,model);
}
}
}

public void LoadMessage()

{
XmlDocument xmlDoc=new XmlDocument();
xmlDoc.Load(HttpContext.Current.Server.MapPath("\\ComponmentTest\\Conf\\UploadFileMessage.xml"));
XmlNodeList nodeList=xmlDoc.SelectSingleNode("MessageConfiguration").ChildNodes;
foreach(XmlNode xn in nodeList)

{
if(xn.Name=="Messages")

{
XmlElement xe=(XmlElement)xn;
MessageModule model=new MessageModule();
model.ModuleDefId=xe.GetAttribute("MessageId");
model.ModuleDefValue=xe.GetAttribute("MessageValue");
Messages.Add(model.ModuleDefId,model);
}
}
}
}

public class CfgInfoModule

{
public String ModuleDefId;
public String ModuleDefValue;
public String ModelDescription;
}

public class MessageModule

{
public String ModuleDefId;
public String ModuleDefValue;
}
像上面出现的xmlDoc.Load(HttpContext.Current.Server.MapPath("
\\ComponmentTest\\Conf\\UploadFileMessage.xml")) 中的
\\ComponmentTest\\Conf\\UploadFileMessage.xml可以设置为自己可以识别的路径。当然也可以在系统配置文件(Web.config&App.config)中定义路径,这个就见仁见智了。
自定义XML文件如下所示:
UploadFileConfigInfo.xml
<?xml version="1.0" encoding="utf-8" ?>
<FileConfiguration>
<ConfigDefinition CfgDefId="UploadPath" CfgDefValue="../ComponmentTest/UploadFiles/" CfgDefDescription=""/>
<ConfigDefinition CfgDefId="MaxFileSize" CfgDefValue="8192" CfgDefDescription=""/>
<ConfigDefinition CfgDefId="AllowFileType" CfgDefValue="*" CfgDefDescription=""/>
<ConfigDefinition CfgDefId="ExcludeFileType" CfgDefValue="exe|dll" CfgDefDescription=""/>
<ConfigDefinition CfgDefId="FileNameLength" CfgDefValue="50" CfgDefDescription=""/>
<ConfigDefinition CfgDefId="RegexPattern" CfgDefValue="([A-Za-z0-9|[_]|[-]|\s]+)([.]){0,1}([A-Za-z0-9|[_]|[-]|\s]+)([.]){0,1}([A-Za-z0-9|[_]|[-]|\s]+)([.]){0,1}([A-Za-z0-9|[_]|[-]|\s]+)([.]){0,1}([A-Za-z0-9|[_]|[-]|\s]+)$" CfgDefDescription=""/>
</FileConfiguration>

UploadFileMessage.xml
<?xml version="1.0" encoding="utf-8" ?>
<MessageConfiguration>
<Messages MessageId="MSG_NoFileExist" MessageValue="Please enter file name."/>
<Messages MessageId="MSG_FileSizeLarge" MessageValue="The file size must low than "/>
<Messages MessageId="MSG_FileNameLong" MessageValue="The file name length must shorter than "/>
<Messages MessageId="MSG_AllowFileType" MessageValue="Please file type,allow upload file type: "/>
<Messages MessageId="MSG_ExFileType" MessageValue="Please do not upload execute file(such as .exe,.dll, and son on)!"/>
<Messages MessageId="MSG_SpecialChar" MessageValue="Please do not enter special charactor in file name."/>
</MessageConfiguration>
你可以根据自己的需要来扩展它,这里就不再赘述了。
接下来回来再看看各个关于上传文件的判断逻辑:
public class FileSize

{
private string _strErrorMessage = "";

public string ErrorMessage

{
get

{
return _strErrorMessage;
}
set

{
_strErrorMessage = value;
}
}

public bool CheckFileSize(HtmlInputFile file, UploadFileCfg cfg)

{
int FileNameLength = Convert.ToInt32(((CfgInfoModule)cfg.CfgInfo["MaxFileSize"]).ModuleDefValue);
int fileSize=file.PostedFile.ContentLength;
//If File size is too large
if(fileSize/1024>FileNameLength)

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_FileSizeLarge"]).ModuleDefValue + ((CfgInfoModule)cfg.CfgInfo["MaxFileSize"]).ModuleDefValue;
return false;
}
return true;
}
}

public class FileType

{
private string _strErrorMessage = "";

public string ErrorMessage

{
get

{
return _strErrorMessage;
}
set

{
_strErrorMessage = value;
}
}

public bool CheckFileType(HtmlInputFile file, UploadFileCfg cfg)

{
string FileOrginName = file.PostedFile.FileName.Substring(file.PostedFile.FileName.LastIndexOf("\\")+1);
string strFileType = FileOrginName.Substring(FileOrginName.LastIndexOf(".")+1);
//Exclude File Type
string ExcludeFileType = ((CfgInfoModule)cfg.CfgInfo["ExcludeFileType"]).ModuleDefValue;
//Allow File Type
string AllowFileType = ((CfgInfoModule)cfg.CfgInfo["AllowFileType"]).ModuleDefValue;

//If set specific allowed file type
if(AllowFileType.IndexOf("*")==-1)

{
if(AllowFileType.ToLower().IndexOf(strFileType.ToLower())==-1)

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_AllowFileType"]).ModuleDefValue + ((CfgInfoModule)cfg.CfgInfo["AllowFileType"]).ModuleDefValue;
return false;
}
}
// Find out exclude file type
if(ExcludeFileType.ToLower().IndexOf(strFileType.ToLower())>-1)

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_ExFileType"]).ModuleDefValue;
return false;
}
return true;
}
}

public class FileExistence

{
private string _strErrorMessage = "";

public string ErrorMessage

{
get

{
return _strErrorMessage;
}
set

{
_strErrorMessage = value;
}
}

public bool IsExistFileName(HtmlInputFile file,UploadFileCfg cfg)

{
//If FileName is not exist ex: C:\UploadFile\
if(file.Value.Length==file.PostedFile.FileName.LastIndexOf("\\")+1)

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_NoFileExist"]).ModuleDefValue;
return false;
}
return true;
}
}

public class FileName

{
private string _strErrorMessage = "";

public string ErrorMessage

{
get

{
return _strErrorMessage;
}
set

{
_strErrorMessage = value;
}
}

public bool CheckFileNameLength(HtmlInputFile file, UploadFileCfg cfg)

{
string FileOrginName = file.PostedFile.FileName.Substring(file.PostedFile.FileName.LastIndexOf("\\")+1);
string FileNameLength = ((CfgInfoModule)cfg.CfgInfo["FileNameLength"]).ModuleDefValue;

//If FileName is too long
if(FileOrginName.Length>Convert.ToInt32(FileNameLength))

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_FileNameLong"]).ModuleDefValue + ((CfgInfoModule)cfg.CfgInfo["FileNameLength"]).ModuleDefValue;
return false;
}
return true;
}
}

public class FileSpecialChar

{
private string _strErrorMessage = "";

public string ErrorMessage

{
get

{
return _strErrorMessage;
}
set

{
_strErrorMessage = value;
}
}

public bool CheckSpecialChar(HtmlInputFile file, UploadFileCfg cfg)

{
string FileOrginName = file.PostedFile.FileName.Substring(file.PostedFile.FileName.LastIndexOf("\\")+1);
//Get File Name Regex Pattern
string FileNamePattern = ((CfgInfoModule)cfg.CfgInfo["RegexPattern"]).ModuleDefValue;
if(!Regex.IsMatch(FileOrginName,FileNamePattern))

{
this.ErrorMessage = ((MessageModule)cfg.Messages["MSG_SpecialChar"]).ModuleDefValue;
return false;
}
return true;
}
}

最后,在系统配置文件(Web.config&App.Config)中设定你的上传路径:
<add key="UploadFilePath" value="../UploadFiles"/>
好了,试下它的效果吧,当同时有几点需要注意:
1. 上传文件的大小不能超过.NET Framework允许的范围。你可以在配置文件中插入下面一行数据:
<httpRuntime maxRequestLength="102400"
useFullyQualifiedRedirectUrl="false" minFreeThreads="8"
minLocalRequestFreeThreads="4" appRequestQueueLimit="1000"/>
maxRequestLength就是允许最大的传输数据量,单位为KB
2. 你是否具有对上传的文件夹有写入权限。