EDM开发过程中遇到的其他问题
1、session:
session记录到数据库中,sql数据库自带程序C:WindowsMicrosoft.NETFrameworkv4.0.30319aspnet_regsql.exe,可以在命令行执行
“C:WindowsMicrosoft.NETFrameworkv4.0.30319aspnet_regsql.exe -S . -E -ssadd -sstype c -d TestSessionStore”会在数据库中生成一个名为TestSessionStore的数据库,这就是为session而生的,然后在web.config中的sessionState改为
<sessionState mode="SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="server=数据库; database=数据库名;uid=帐号;pwd=密码;" cookieless="false" timeout="60"> </sessionState>
这样,再用sessin就会记录在数据库中了。不过如果直接运行.exe程序手动生成数据库,会报错,提示无会话状态。
2、task:
用多线程方法可以减少发送大量邮件花费时间长的问题(SMTP限制之后再说),task是对ThreadPool线程池的封装,相对于线程池具有很多优势,比如:(1)ThreadPool不支持线程的取消、完成、失败通知等交互性操作;(2)ThreadPool不支持线程执行的先后次序;通过对ThreadPool进行封装,于是.net Framework4.0有了TPL和Task。也就是说,相对于线程池,task使我能对线程的可控性大大提高了。
(1)普通用法:
Task t = new Task(() => { Console.WriteLine("任务开始"); }); t.Start(); t.ContinueWith((task) => { Console.WriteLine("任务完成"); });
(2)任物工厂:
Task[] tasks = new Task[] { taskFactory.StartNew(() => Add(cts.Token)), taskFactory.StartNew(() => Add(cts.Token)), taskFactory.StartNew(() => Add(cts.Token)) }; //CancellationToken.None指示TasksEnded不能被取消 taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None);
CancellationTokenSource是通知 CancellationToken,告知其应被取消。当其被实例化后,执行.Canale()方法,即可取消线程。
task可以等待某个线程执行完成后再执行:
t1.Wait(); //等待任务t1完成 Task.WaitAll(t2, t3); //等待任务t2和t3完成 t4.ContinueWith(TaskEndedByCatch); //t4执行完成后继续执行TaskEndedByCatch方法 taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None); //工厂内所有线程执行完毕后,执行TasksEnded方法,CancellationToken.None指示此方法不能被取消。
3、解压:
对于传入的文件,可能是文本文件,也可能是压缩文件,这就要求将传入的压缩文件解压并对文件路径进行记录,而且由于压缩文件格式不确定,所以调用WinRAR软件进行解压。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 利用 WinRAR 进行解压缩 3 /// </summary> 4 /// <param name="path">文件解压路径(绝对路径)</param> 5 /// <param name="rarPath">将要解压缩文件的存放目录(绝对路径)</param> 6 /// <param name="rarName">将要解压缩文件名(包括后缀)</param> 7 /// <returns>true 或 false。解压缩成功返回 true,反之,false。</returns> 8 public bool UnRarOrZip(string path, string rarPath, string rarName) 9 { 10 bool flag = false; 11 try 12 { 13 RegistryKey regkey = Registry.ClassesRoot.OpenSubKey(@"WinRAR.ZIPshellopencommand");//根据注册表,获取WinRAR的运行路径 14 if (regkey != null) 15 { 16 Object regvalue = regkey.GetValue(""); 17 string rarexe = regvalue.ToString(); 18 regkey.Close(); 19 rarexe = rarexe.Substring(1, rarexe.Length - 7); 20 21 Directory.CreateDirectory(path); 22 //解压缩命令,相当于在要压缩文件(rarName)上点右键->WinRAR->解压到当前文件夹 23 string cmd = string.Format("x {0} {1} -y", 24 rarName, 25 path); 26 var startinfo = new ProcessStartInfo 27 { 28 FileName = rarexe, 29 Arguments = cmd, 30 WindowStyle = ProcessWindowStyle.Hidden, 31 WorkingDirectory = rarPath 32 }; 33 34 var process = new Process {StartInfo = startinfo}; 35 process.Start(); 36 process.WaitForExit(); 37 if (process.HasExited) 38 { 39 flag = true; 40 } 41 process.Close(); 42 } 43 } 44 catch (Exception e) 45 { 46 throw e; 47 } 48 return flag; 49 } 50 51 public void Dispose() 52 { 53 throw new NotImplementedException(); 54 } 55 }
4、文件操作:
系统中需要对文件和文件夹进行读写操作。
创建文件或文件夹:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //创建文件夹 2 public void CreateDirectory(string pathName) 3 { 4 if (!Directory.Exists(pathName)) 5 { 6 Directory.CreateDirectory(pathName); 7 } 8 } 9 10 //创建文件 11 public void CreateFile(string pathName) 12 { 13 if (!File.Exists(pathName)) 14 { 15 File.Create(pathName); 16 } 17 }
获取文件名或文件夹名:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //获取目录下所有文件名 2 public List<string> GetAllFiles(string path) 3 { 4 var dir = new DirectoryInfo(path); 5 var fiList = new List<FileInfo>(); 6 if (dir.Exists) 7 { 8 fiList.AddRange(dir.GetFiles()); 9 } 10 var fileName = new List<string>(); 11 if (fiList.Count != 0) 12 { 13 fileName.AddRange(fiList.Select(dl => dl.Name)); 14 } 15 return fileName; 16 } 17 18 //获取目录下所有文件夹名 19 public List<string> GetAllDirectorys(string path) 20 { 21 var dir = new DirectoryInfo(path); 22 var diList = new List<DirectoryInfo>(); 23 if (dir.Exists) 24 { 25 diList.AddRange(dir.GetDirectories()); 26 } 27 var fileName = new List<string>(); 28 if (diList.Count != 0) 29 { 30 fileName.AddRange(diList.Select(dl => dl.Name)); 31 } 32 return fileName; 33 }
删除文件:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //删除文件 2 public void DeleteFile(string path) 3 { 4 //判断文件是不是存在 5 if (!File.Exists(path)) return; 6 //文件删除 7 File.Delete(path); 8 }
清空文件夹:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //清空文件夹 2 public void DeleteDirectory(string path) 3 { 4 //判断文件是不是存在 5 if (!Directory.Exists(path)) return; 6 //文件夹清空 7 DeleteFolder(path); 8 } 9 public static void DeleteFolder(string dir) 10 { 11 foreach (string d in Directory.GetFileSystemEntries(dir)) 12 { 13 if (File.Exists(d)) 14 { 15 FileInfo fi = new FileInfo(d); 16 if (fi.Attributes.ToString().IndexOf("ReadOnly", System.StringComparison.Ordinal) != -1) 17 fi.Attributes = FileAttributes.Normal; 18 File.Delete(d);//直接删除其中的文件 19 } 20 else 21 { 22 var d1 = new DirectoryInfo(d); 23 if (d1.GetFiles().Length != 0) 24 { 25 DeleteFolder(d1.FullName);////递归删除子文件夹 26 } 27 Directory.Delete(d); 28 } 29 } 30 }
获取目录下第一次出现文件的路径:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public string GetNewUrl(string pathUrl, string pathName) 2 { 3 var files = GetAllFiles(pathUrl); 4 if (files.Count == 0) 5 { 6 var directions = GetAllDirectorys(pathUrl); 7 if (directions.Count > 0) 8 { 9 pathName += "/" + directions.FirstOrDefault(); 10 GetNewUrl(pathUrl + "\" + directions.FirstOrDefault(), pathName); 11 } 12 } 13 return pathName; 14 }
5、对于excel文件的导入导出操作:
系统数据导入可能是txt文件,也可能是excel文件。对于导入的Excel文件,使用NPOI进行操作。
excel文件操作类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 private HSSFWorkbook _hssfworkbook; 2 3 public void InitializeWorkbook(string path) 4 { 5 using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) 6 { 7 _hssfworkbook = new HSSFWorkbook(file); 8 } 9 } 10 11 public void InitializeWorkbook(FileUpload uploadfile) 12 { 13 uploadfile.SaveAs(HttpContext.Current.Server.MapPath("~/Content/excel.xls")); 14 string path = HttpContext.Current.Server.MapPath("~/Content/excel.xls"); 15 using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) 16 { 17 _hssfworkbook = new HSSFWorkbook(file); 18 } 19 } 20 21 /// <summary> 22 /// 数据导出 23 /// </summary> 24 /// <param name="sheetName">Excel Sheet名称</param> 25 /// <param name="cellNames">列名</param> 26 /// <param name="setCellValue">设置列值的委托方法</param> 27 /// <returns></returns> 28 public MemoryStream ExportEdm(string sheetName, string[] cellNames, Action<ISheet> setCellValue) 29 { 30 using (var output = new MemoryStream()) 31 { 32 IWorkbook workBook = new HSSFWorkbook(); 33 var sheet = workBook.CreateSheet(sheetName); 34 var headRow = sheet.CreateRow(0); 35 for (int i = 0; i < cellNames.Length; i++) 36 headRow.CreateCell(i).SetCellValue(cellNames[i]); 37 setCellValue(sheet); 38 for (int i = 0; i < cellNames.Length; i++) 39 sheet.AutoSizeColumn(i); 40 workBook.Write(output); 41 return output; 42 } 43 }
excel导入导出实例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// Excel数据导入 3 /// </summary> 4 public void GetExcel(string path) 5 { 6 var uplodeExcel = new ExcelHelper(); 7 uplodeExcel.InitializeWorkbook(path); 8 var list = uplodeExcel.SetCurrentSheet(); 9 } 10 11 /// <summary> 12 /// Excel导出EDM 13 /// </summary> 14 public ActionResult ReportExcel() 15 { 16 var list = (from entity in models 17 let model = _sendService.GetCountList(entity.SendTableName) 18 select new SendTypeStatis 19 {}).ToList(); 20 string[] cellNames = 21 { 22 "EDM名称", "真实路径" 23 }; 24 var output = new ReportExcel().ExportEdm("EDM导出", cellNames, r => 25 { 26 if (!list.Any()) return; 27 var rowNumber = 1; 28 foreach (var ml in list) 29 { 30 var number = 0; 31 var row = r.CreateRow(rowNumber++); 32 row.CreateCell(number++).SetCellValue(ml.EdmName); 33 row.CreateCell(number).SetCellValue(ml.EdmNewUrl); 34 } 35 }); 36 string saveAs = string.Format("数据导出-{0:d}.xls", DateTime.Now.Ticks); 37 Response.ContentType = "application/vnd.ms-excel"; 38 Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", saveAs)); 39 Response.BinaryWrite(output.GetBuffer()); 40 Response.End(); 41 42 return Json("success"); 43 }