几年前,一篇《ASP.NET开发人员经常使用的三十三种代码》非常流行,它总结了一些经常在ASP.NET开发中使用到的代码,直接可以拿来使用。今天重读这篇文章,有感而发,善于总结也是进步,于是我也从我的项目中总结一些常用的代码片段,分享给各位园友。
写文本文件
TextWriter tw = new StreamWriter("date.txt");
tw.WriteLine(DateTime.Now);
tw.Close();
读文本文件
写法一
Textreader tr = new StreamReader("date.txt");
Console.WriteLine(tr.ReadLine());
tr.Close();
写法二
StreamReader reader = new StreamReader("date.txt");
Console.WriteLine(reader.ReadLine());
reader.Close();
其实,上面的写文本文件和读文本文件,都有一个bug,当程序中有代码改变当前目录时,date.txt的目录就是这个被改变的目录,而不是我们期待的当前应用程序所有的目录。所以,推荐的写法是这样的
string file = "Cnblogs.txt";
string cnblogs = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, file);
if (File.Exists(cnblogs))
{using (StreamReader reader = File.OpenText(cnblogs)){rtfCnblogs.Text = reader.ReadToEnd();}
}
加入了完整的文件名路径,这样才是正确的读写文件的方法。如果是ASP.NET应用程序,可以用Server.MapPath代替,
或是HttpContext.Current.Request.PhysicalApplicationPath。
跨线程访问控件
delegate void dSetText(string text);
private void SetText(string text){
if (InvokeRequired)
{
dSetText d = new dSetText(SetText);
this.Invoke(d);
}
else{
this.textBox1.Text = ;
}}
调用Code Smith模板
CodeTemplateCompiler compiler = new CodeTemplateCompiler(@"c: est.cst");
compiler.Compile(); if (compiler.Errors.Count == 0){
CodeTemplate t = compiler.CreateInstance();
this.txtSql.Text = t.RenderToString();
}
compiler.Cleanup();
compiler = null;
如果是x64的系统,请设置Target为x86(need to set the program to compile as X86)。
设置程序集运行时版本
当旧的程序是以.NET 2.0编译的,又无法升级到.NET 4.0,而有部分组件是以.NET编译的,在运行时,会抛出混合程序集的异常,需要修改配置文件,请参考这个片段
"1.0"?>
"true">
"true" imageVersion="v4.0.30319" version="v4.0.30319"/>
这个需求源于,Code Smith 5.0是以.NET 2.0编译的。在我的代码生成可器中,它用来反射读取程序集信息,生成代码,而这个被读取的程序集的Target是.NET 4.0,这时,你需要这个技巧来解决运行时的问题。
另一个场景是ILMerge,用于合并.NET程序集的工具,只有.NET 2.0的版本,要可以合并.NET 4.0的程序集,也需要运用这个技巧(ILMerge config file for executing within the CLR v4.0 runtime)。
枚举类型的反射调用
在有些场景,我们需要把反射的参数值传到对象的方法中,而参数值是enum类型,这实现起来并不简单。
请参考codeproject中这的篇文章《Setting Enum's Through Reflection 》,它的经典代码是这样的
int enumValue1 = (int)enumItem1.GetValue(enumType);
int enumValue2 = (int)enumItem2.GetValue(enumType);
int currentValue = (int)flagsInfo.GetValue(remoteObject, null);
int newValue = currentValue | enumValue1 | enumValue2;
举例说明,我需要反射生成ReportViewer控件的对象实例,并且要传一个Mode值给它(Server,LocalReport)以表示是本地报表,还是取服务器报表。这种情况下,非得用反射的方式传入值。
在我的.NET通用平台中,也应用到这项技术,以反射方式创建CrystalReportViewer报表控件,再传入参数值。这种方式稍微复杂一些,但是对比它带来的灵活性,是非常值得的。
目录选择功能
FolderBrowserDialog dlg = new FolderBrowserDialog();
if (!string.IsNullOrEmpty(txtPath.Text))dlg.SelectedPath = txtPath.Text;
if (dlg.ShowDialog() == DialogResult.OK)
{txtPath.Text = dlg.SelectedPath;
}
文件选择功能
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "All File(*.*)|*.*";
if (dlg.ShowDialog() == DialogResult.OK)
{txtPath.Text = dlg.FileName;
}
Filter是经常容易忘记的选项,再举一个例子
dlg.Filter = "Xml file (*.xml)|*.xml|All Files|*.*";
读取嵌入到程序集中的资源文件
Assembly assm = Assembly.GetAssembly(typeof(DatabaseCleanup));
string file = "DatabaseCleanup.txt";
Stream input = assm.GetManifestResourceStream("DataLoader.Resource" + "." + file);
StreamReader reader=new StreamReader(input);
string sql=reader.ReadToEnd();
reader.Close();
只要可能,对只读的不需要修改的配置选项资源(SQL语句,文本文件),尽可能的使用Embedded Resource方式。
微软企业库的调用方式
经过一层简单的封装,以下面的这种方式来调用企业库以访问数据库
EnterpriseLibraryShared.ConnectonString =ConnectionString;
Microsoft.Practices.EnterpriseLibrary.Data.Database m_commonDb = DatabaseFactory.CreateDatabase();
DbCommand cmd = m_commonDb.GetSqlStringCommand(sql);
int rowAffected = m_commonDb.ExecuteNonQuery(cmd);
我把企业库的连接字符串放到一个static class中,这样可以简化调用方式,不必要一定要加App/Web.config文件。
监控文件或目录的变化
这个功能比较常用,在Data Loader也有一个PDF Watcher的程序,以监控指定的目录是否有新加入的PDF文件(可能来自远程传输,或是从网页中下载回来),然后对它进转换,导入到文档服务器中。
public void StartMonitor(string path)
{ FileSystemWatcher watcher = new FileSystemWatcher();watcher.Path = path;watcher.NotifyFilter = NotifyFilters.FileName;// Only watch pdf files.watcher.Filter = "*.pdf";watcher.Created += new FileSystemEventHandler(OnChanged);watcher.EnableRaisingEvents = true;
}// Event handler for when a file is created in the watched folder
private void OnChanged(object source, FileSystemEventArgs e)
{string word = DocumentUtility.ConvertPdfToDoc(e.FullPath);
}
希望可以帮助到你。