C#——文件上传(一般处理程序ashx)
Framework版本:.Net Framework 4
1、FileInfo实体
using System; using System.Collections.Generic; using System.Linq; using System.Web; using MongoDB.Bson; using ReligionServer.util; using ReligionServer.constant; namespace ReligionServer.Model { //为什么会有多余的get set方法,因为测试写的,没有删 //封装的一个文件类, 文件基本信息 public class FileInfo { public ObjectId _id; public String FileCode { get; set; }//目前还没有研究出ObjectId序列化的最好解决方式, 所以暂时使用FileCode替代Id public String Name { get; set; } public String Type { get; set; } public String Desc { get; set; } public String Path { get; set; } public int Access { get; set; } public String ForeignKey { get; set; } public DateTime CreateTime { get; set; } public String TypeCode { get; set; }//辅助字段 public FileInfo() { } public void set_Id(ObjectId id) { this._id = id; } public ObjectId get_Id() { return this._id; } public void setFileCode() { this.FileCode = CommonUtil.CreateId(); } public String getFileCode() { return this.FileCode; } public void setName(String name) { this.Name = name; } public String getName() { return this.Name; } public void setType(String type) { this.Type = FileTypeConstant.GetType(type); } public String getType() { return this.Type; } public void setDesc(String desc) { this.Desc = desc; } public String getDesc() { return this.Desc; } public void setPath(String path) { this.Path = path; } public String getPath() { return this.Path; } public void setAccess(int access) { this.Access = access; } public int getAccess() { return this.Access; } public void setForeignKey() { this.ForeignKey = CommonUtil.CreateId(); } public String getForeignKey() { return this.ForeignKey; } public void setCreateTime() { this.CreateTime = DateTime.Now; } public DateTime getCreateTime() { return this.CreateTime; } public void setTypeCode(String code) { this.TypeCode = code; } public String getTypeCode() { return this.TypeCode; } } }
2、Handler具体实现
using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Web; using ReligionServer.util; using ReligionServer.Model; using ReligionServer.service; using System.Text.RegularExpressions; namespace ReligionServer.handler { /// <summary> /// FileHandler 的摘要说明 /// 处理文件请求 /// </summary> public class FileHandler : BaseHandler, IHttpHandler { private FileInfoService fileInfoService = new FileInfoService(); private readonly String targetSavePath = "~/ReligionFile/"; public void ProcessRequest(HttpContext context) { base.InitAction(context); } #region 文件上传 //和第三方表关联的文件上传初始化逻辑 public void Upload_Foreign(HttpContext context) { Model.FileInfo fileInfo = InitFileInfo(context, 0); if (CommonUtil.IsEmpty(fileInfo.getForeignKey())) { NoParams<Model.FileInfo>(context, "关联外键为空, 还请检测关联属性是否上传成功, 外键是否为空"); } else if (base.IsEmpty(fileInfo.getTypeCode())) { fileInfo.setTypeCode("0"); NoParams<Model.FileInfo>(context, "TypeCode is null or '' ..."); } else { List<Model.FileInfo> uploadFileList = FileInsert(context, InitFileInfo(context, 0)); if (uploadFileList.Count == 0) { Error<String>(context, new List<String>() { "上传失败: 后台获取文件信息失败" }); } else { int errorCount = (int)context.Items["FileUploadErrorCount"]; int successCount = uploadFileList.Count - errorCount; Success<String>(context, new List<String>() { "一共上传 " + uploadFileList.Count + "个文件,其中成功 " + successCount + "个,失败" + errorCount + "个" }); } } } //文件上传初始化逻辑 public void Upload(HttpContext context) { Model.FileInfo fileInfo = InitFileInfo(context, 1); if (base.IsEmpty(fileInfo.getTypeCode())) { fileInfo.setTypeCode("0"); NoParams<Model.FileInfo>(context, "TypeCode is null or '' ..."); } else { List<Model.FileInfo> uploadFileList = FileInsert(context, fileInfo); if (uploadFileList.Count == 0) { Error<String>(context, new List<String>() { "上传失败: 后台获取文件信息失败" }); } else { int errorCount = (int)context.Items["FileUploadErrorCount"]; int successCount = uploadFileList.Count - errorCount; Success<String>(context, new List<String>() { "一共上传 " + uploadFileList.Count + "个文件,其中成功 " + successCount + "个,失败" + errorCount + "个" }); } } } /// <summary> /// 供类相互调用的文件上传 /// </summary> /// <param name="context"></param> /// <param name="foreignKey"></param> /// <returns></returns> public List<Model.FileInfo> Upload_Invoke(HttpContext context, String foreignKey) { if (!base.IsEmpty(foreignKey)) { Model.FileInfo fileInfo = InitFileInfo(context, 0); fileInfo.ForeignKey = foreignKey; List<Model.FileInfo> uploadFileList = FileInsert(context, fileInfo); return uploadFileList; } return new List<Model.FileInfo>(); } //执行文件转存以及数据库记录插入的方法 private List<Model.FileInfo> FileInsert(HttpContext context, Model.FileInfo fileInfo) { List<Model.FileInfo> fileInfoList = new List<Model.FileInfo>(); //List<Model.FileInfo> fileInfoList = new List<Model.FileInfo>(); String directoryName = DateUtil.CurrentDateTimeValue();//文件夹名称 //HttpContext.Current.Request.PhysicalApplicationPath 获取当前正在执行的服务器应用程序的根目录的物理文件系统路径 String targetPhysicalFilePath = HttpContext.Current.Request.PhysicalApplicationPath + "ReligionFile/" + directoryName; //不存在就创建 if (!Directory.Exists(targetPhysicalFilePath)) { Directory.CreateDirectory(targetPhysicalFilePath); } //获取上传文件集合 HttpFileCollection fileCollection = context.Request.Files; //HttpPostedFile temp = context.Request.Files["regfile"];//测试 //String tempe = context.Request.Params["regfile"]; //HttpPostedFileWrapper fileWrapper = context.Request.Files[0]; Model.FileInfo tempFileInfo = null; if (fileCollection.Count > 0) { HttpPostedFile item = null; for (int i = 0; i < fileCollection.Count; i++) { item = fileCollection[i]; String suffix = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];//获取文件的后缀名 tempFileInfo = new Model.FileInfo(); tempFileInfo = (Model.FileInfo)BeanUtil.PropCopy(fileInfo, tempFileInfo); //tempFileInfo.set_Id(CommonUtil.CreateObjectId());这样设置Id是无效的 tempFileInfo.setName(item.FileName);//存的是以前的文件名, 是否有意义 tempFileInfo.setFileCode(); tempFileInfo.setType(suffix); tempFileInfo.setCreateTime(); suffix = "." + suffix; if (suffix.ToLower().Equals(".txt")) { suffix = ".doc";//这里是否有必要? 这是个问题 } String realFileName = Guid.NewGuid().ToString() + suffix; tempFileInfo.setTypeCode(tempFileInfo.getTypeCode() + ":" + "ReligionFile/" + directoryName + "/" + realFileName); tempFileInfo.setPath("ReligionFile/" + directoryName + "/" + realFileName); item.SaveAs(context.Server.MapPath(targetSavePath + directoryName + "/" + realFileName));//文件转存 必须是文件的根目录, 而且不能使虚拟目录 fileInfoList.Add(tempFileInfo); } //foreach (String key in fileCollection) { //这里前台只有一个文件选择框, 那么多文件时keys都是相同的, // HttpPostedFile item = fileCollection[key]; // String suffix = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];//获取文件的后缀名 // fileInfo.setName(item.FileName); // fileInfo.setFileCode(); // fileInfo.setType(suffix); // fileInfo.setCreateTime(); // suffix = "." + suffix; // if (suffix.ToLower().Equals(".txt")) { // suffix = ".doc";//这里是否有必要? 这是个问题 // } // String realFileName = Guid.NewGuid().ToString() + suffix; // fileInfo.setTypeCode(fileInfo.getTypeCode() + ":" + "ReligionFile/" + directoryName + realFileName); // item.SaveAs(context.Server.MapPath(targetSavePath + directoryName + "/" + realFileName));//文件转存 必须是文件的根目录, 而且不能使虚拟目录 // fileInfoList.Add(fileInfo); //} int errorCount = fileInfoService.InsertBatchFileInfo(fileInfoList);//文件信息批量入表, 返回失败个数 context.Items.Add("FileUploadErrorCount", errorCount); } return fileInfoList; } /// <summary> /// Base64格式的图片上传 /// </summary> /// <param name="context"></param> public void Insert_Base64_Img(HttpContext context) { vo.Base64Image base64Image = base.GetInstance<vo.Base64Image>(context, new vo.Base64Image()); if (base.IsEmpty(base64Image.Base64String)) { NoParams<vo.Base64Image>(context, "上传参数存在空值"); } else { List<Model.FileInfo> fileInfoList = util.ImageUtil.Base64ImageInsertBatch(context, util.ArrraysUtil.PurifyArrays<String>(Regex.Split(base64Image.Base64String, "c#", RegexOptions.IgnoreCase))); if (fileInfoList.Count > 0) { int errorCount = fileInfoService.InsertBatchFileInfo(fileInfoList); int successCount = fileInfoList.Count - errorCount; Success<String>(context, new List<String>() { "一共上传 " + fileInfoList.Count + "个文件,其中成功 " + successCount + "个,失败" + errorCount + "个" }); } else { Error<String>(context, new List<String>() { "上传失败: 后台将Base64转存时失败" }); } } } #endregion #region 文件删除 /// <summary> /// 根据ObjectId删除指定的文件信息 /// </summary> /// <param name="context"></param> public void Del_ObjectId(HttpContext context) { //暂时不做 } /// <summary> /// 根据FileCode删除指定的文件信息 /// </summary> /// <param name="context"></param> public void Del_FileCode(HttpContext context) { Model.FileInfo fileInfo = this.InitFileInfo(context, -1); fileInfo = fileInfoService.FindFileInfoByFileCode(fileInfo.getFileCode()); if (fileInfo != null) { if (fileInfoService.RemoveFileInfoByFileCode(fileInfo.getFileCode())) { RemoveLocalFile(fileInfo); Success<Model.FileInfo>(context, new List<Model.FileInfo>() { fileInfo }); } else { Error<Model.FileInfo>(context, new List<Model.FileInfo>() { fileInfo }); } } else { NoParams<Model.FileInfo>(context, "该条记录不存在,无法删除"); } } /// <summary> /// 根据外键ForeignKey删除所关联的文件信息 /// </summary> /// <param name="context"></param> public void Del_ForeignKey(HttpContext context) { } /// <summary> /// 根据传递进来的FileInfo的path字段删除服务器上对应的文件 /// </summary> /// <param name="fileInfo"></param> private void RemoveLocalFile(Model.FileInfo fileInfo) { System.Diagnostics.Debug.WriteLine(HttpContext.Current.Request.PhysicalApplicationPath + fileInfo.getPath()); //FileUtil.RemoveFile(context.Request.PhysicalApplicationPath + fileInfo.getPath()); FileUtil.RemoveFile(HttpContext.Current.Request.PhysicalApplicationPath + fileInfo.getPath()); } #endregion #region 文件修改 /// <summary> /// 根据FileCode修改指定的文件信息 /// </summary> /// <param name="context"></param> public void Update_FileCode(HttpContext context) { Model.FileInfo target = InitFileInfo(context, -1); String fileCode = target.getFileCode(); List<Model.FileInfo> list = null; if (CommonUtil.IsEmpty(target.getForeignKey()) || CommonUtil.IsEmpty(target.getFileCode())) { NoParams<Model.FileInfo>(context, "关联外键ForeignKey或FileCode为空"); } else { list = FileInsert(context, InitFileInfo(context, 0)); } if (null != list) { target = list[0]; target.FileCode = fileCode; Model.FileInfo source = fileInfoService.FindFileInfoByFileCode(target.getFileCode()); if (null != source) { target._id = source._id; target.Access = source.Access; target.ForeignKey = source.ForeignKey; if (fileInfoService.UpdateAllByFileCode(target)) { RemoveLocalFile(source);//如果上传成功, 就将原来的文件删除 Success<Model.FileInfo>(context, new List<Model.FileInfo>() { fileInfoService.FindFileInfoByFileCode(target.FileCode) }); } else { Error<Model.FileInfo>(context, new List<Model.FileInfo>() { target }); RemoveLocalFile(target);//如果更新失败, 就将上传的文件删除 } } else { Init<Model.FileInfo>(context, "300", "", new List<Model.FileInfo>() { }); } } } #endregion #region 文件查找 /// <summary> /// 根据FileCode查找指定的文件信息 /// </summary> /// <param name="context"></param> public void Query_FileCode(HttpContext context) { Model.FileInfo fileInfo = fileInfoService.FindFileInfoByFileCode(this.InitFileInfo(context, -1).FileCode); if (fileInfo == null) { NoParams<Model.FileInfo>(context, "该记录不存在"); } else { Success<Model.FileInfo>(context, new List<Model.FileInfo>() { fileInfo }); } } /// <summary> /// 根据ForeignKey查询所有的文件信息 /// </summary> /// <param name="context"></param> public void Query_Foreign(HttpContext context) { //Model.FileInfo info = this.InitFileInfo(context, -1); List<Model.FileInfo> list = fileInfoService.FindFileInfoListByForeignKey(this.InitFileInfo(context, -1).ForeignKey); //if (list == null || list.Count == 0) { // NoParams<Model.FileInfo>(context, "没有匹配的记录"); //} else { // Success<Model.FileInfo>(context, list); //} Success<Model.FileInfo>(context, list); } #endregion //初始化FileInfo private Model.FileInfo InitFileInfo(HttpContext context, int access) { Model.FileInfo fileInfo = ParametersUtil.GetInstanceFormRequest<Model.FileInfo>(context, new Model.FileInfo());//这里主要是获取ForeignKey if (access != -1) { fileInfo.setAccess(access);//设置文件资源类型 {0表示关联; 1表示独立资源,没有关联} -1表示不作处理 } return fileInfo; } public bool IsReusable { get { return false; } } } }