文件上传无论在软件还是在网站上都十分常见,我今天再把它拿出来,讲一下,主要讲一下它的设计思想和实现技术,为了它的通用性,我把它做在了WEB.Service项目里,即它是针对服务器的,它的结构是关联UI(WEB)层与Service层(BLL)的桥梁.
结构
上传基类:
上传文件的接口规范:
接口的实现:
UI层调用WEB.Service层的上传功能:(附代码)
public class FileUploadController : Controller
{ WEB.Services.IFileUpload iFileUpload = null; public FileUploadController() { iFileUpload = new WEB.Services.FileUpload();}
#region 文件上传 public ActionResult uploadheadpic() { return View();}
[HttpPost]
public ActionResult uploadheadpic(FormCollection formcollection) { if (Request.Files.Count > 0) {HttpPostedFileBase file = Request.Files[0];
Entity.Commons.VMessage vm = iFileUpload.Image(WEB.Services.UpLoadType.DownloadUrl, file);
if (vm.IsComplete)TempData["PicUrl"] = "{result:true,msg:\"" + vm[0].Replace("\"", "") + "\"}";
elseTempData["PicUrl"] = "{result:false,msg:\"" + vm[0].Replace("\"", "") + "\"}";
}
return View();}
#endregion}
下面公布一下上传的基类代码:(如果有设计不合理的地方,欢迎大家留言)
namespace WEB.Services{ #region 所需枚举 /// <summary> /// 文件上传类型 /// </summary>public enum UpLoadType
{ /// <summary> /// 下载地址 /// </summary>DownloadUrl = 0,
/// <summary> /// 文件地址 /// </summary>FileUrl = 1,
}
/// <summary> /// 上传错误信息列举 /// </summary>public enum WarnEnum
{ImgContentType,
ImgContentLength,
ImgExtension,
}
#endregion #region 文件上传基本服务类 /// <summary> /// 文件上传基本服务类 /// </summary>public abstract class FileUploadBase
{ /// <summary> /// 图片MIME /// </summary>protected static List<string> imgMIME = new List<string>
{ "application/x-zip-compressed", "application/octet-stream", "application/x-compressed", "application/x-rar-compressed", "application/zip", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword", "image/jpeg", "image/gif", "audio/x-mpeg", "audio/x-wma", "application/x-shockwave-flash", "video/x-ms-wmv", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.presentationml.presentation",};
/// <summary> /// 验证消息字典 /// </summary>protected static Dictionary<WarnEnum, string> msgDIC = new Dictionary<WarnEnum, string>
{ {WarnEnum.ImgContentType ,"只能上传指定类型的文件!" }, {WarnEnum.ImgContentLength ,"只能上传文件大小为{0}以下!" }, {WarnEnum.ImgExtension , "文件的扩展文件不正确"}};
/// <summary> /// 相对地址字典 /// </summary>protected static Dictionary<UpLoadType, string> relativePathDic = new Dictionary<UpLoadType, string>
{ {UpLoadType.DownloadUrl ,@"DownLoad/" }, {UpLoadType.FileUrl ,@"FileUpload/" },};
/// <summary> /// 图片后缀 /// </summary>protected static string[] imgExtension = { "xls", "doc", "zip", "rar", "ppt", "docx", "xlsx", "pptx",
"mp3", "wma", "swf", "jpg", "jpeg", "gif" };
}
#endregion}
文件上传实现类:
public class FileUpload : FileUploadBase, IFileUpload
{ #region 文件上级WWW服务器及图像服务器 public Entity.Commons.VMessage Image(UpLoadType type, HttpPostedFileBase hpf) {HttpRequest Request = HttpContext.Current.Request;
Entity.Commons.VMessage vmsg = new Entity.Commons.VMessage();if (this.IsIamgeVaild(type, hpf))
{string relativePath = string.Format(VConfig.BaseConfigers.LocationUploadPath, relativePathDic[type]);
string path = HttpContext.Current.Server.MapPath(relativePath); #region 建立路径 DirectoryInfo di = new DirectoryInfo(path); if (!di.Exists) {di.Create();
}
#endregion string guid = Guid.NewGuid().ToString();string fileName = string.Format("{0}{1}", guid, new FileInfo(hpf.FileName).Extension);//上传文件的名称
hpf.SaveAs(string.Format("{0}{1}", path, fileName));
vmsg.Clear();
vmsg.AddItem(string.Format("{0}://{1}{2}{3}",
Request.Url.Scheme,
Request.Url.Authority,
relativePath.Replace('\\', '/'),
fileName
)
);
vmsg.AddItem(guid);
vmsg.IsComplete = true;
}
else
{vmsg.AddItemRange(this.GetRuleViolations(type, hpf));
vmsg.IsComplete = false;
}
return vmsg;
}
public Entity.Commons.VMessage ImageToServer(string url)
{Entity.Commons.VMessage vmsg = new Entity.Commons.VMessage();
Uri uri = new Uri(url);
string fileName = uri.Segments[uri.Segments.Length - 1];
string typeStr = uri.Segments[uri.Segments.Length - 2];
VCommons.Utils.FileUpLoad(
string.Format(BaseConfigers.DefaultUploadUri, typeStr.TrimEnd('/')),HttpContext.Current.Server.MapPath(uri.LocalPath)
);
vmsg.IsComplete = true;
vmsg.AddItem(
string.Format("{0}://{1}/upload/{2}{3}",HttpContext.Current.Request.Url.Scheme,
BaseConfigers.ImageServerHost,
typeStr,
fileName
)
);
return vmsg;
}
#endregion
#region 验证文件
internal bool IsIamgeVaild(UpLoadType type, HttpPostedFileBase hpf)
{return this.GetRuleViolations(type, hpf).Count() == 0;
}
/// <summary>
/// 验证文件
/// </summary>
/// <param name="hpf"></param>
/// <returns></returns>
internal IEnumerable<string> GetRuleViolations(UpLoadType type, HttpPostedFileBase hpf)
{if (!imgMIME.Contains(hpf.ContentType))// MIME
yield return msgDIC[WarnEnum.ImgContentType];
int contentLength = this.GetContentLengthByType(type);//文件大小
if (hpf.ContentLength > contentLength)
yield return string.Format(msgDIC[WarnEnum.ImgContentLength], contentLength / 1024);
if (!imgExtension.Contains(hpf.FileName.Substring(hpf.FileName.LastIndexOf('.') + 1)))//文件后缀yield return msgDIC[WarnEnum.ImgExtension];
yield break;
}
#endregion #region 根据 FileUpLoadContentLengthType 类型 获取相应的大小 /// <summary> /// 根据 FileUpLoadContentLengthType 类型 获取相应的大小 /// </summary> /// <param name="type">文件上传大小枚举值</param> /// <returns>返回</returns> int GetContentLengthByType(UpLoadType type) { switch (type) { case UpLoadType.DownloadUrl:return 200000; //200M
case UpLoadType.FileUrl: return 200000; default:throw new Exception("可能有错误");
}
}
#endregion}



