区别不同浏览器,CSS hack写法:
区别IE6与FF:
#demo{
background:orange;
*background:blue;
}
区别IE6与IE7:
#demo{
background:green !important;
background:blue;
}
区别IE7与FF:
#demo{
background:orange;
*background:green;
}
区别FF,IE7,IE6:
#demo{
background:orange;
*background:green !important;
*background:blue;
}
注:IE都能识别*;标准浏览器(如FF)不能识别*;
IE6能识别*,但不能识别 !important,
IE7能识别*,也能识别!important;
FF不能识别*,但能识别!important;
我自己是使用下划线,我最开始区别 ie6 和 FF 的时候 习惯在代码里面加 /**/如: margin-top:1px;
margin-top/**/:5px;去实现我现在改变了写法
#demo{
background:orange;
_background:green !important;
_background:blue;
}
理由和上面说的一样,FF不认_ ie认_ ie6不认识!important 根据这些区别,采用不同的Hack 手法
[教程]将Flex与Spring框架集成
随着富Internet应用(RIA)技术的不断成熟,将类似于Adobe Flex这样的RIA应用与健壮的服务器端技术进行集成就变得越来越重要了。Java开发者最喜欢的服务器端框架之一Spring将在这个过程中扮演着重要的角色。
RIAvolutionize the Web的Marco Casario解释到他为何建议BlazeDS成为Spring与Flex结合的企业系统时说道:“Spring是一个开源框架,可以让开发人员开发起来 更加轻松。如果使用标准的JEE方式,你需要编写大量无用或者冗余的代码,还可能花费大量时间去实现J2EE的设计模式,而这些模式仅仅是为了应对技术上 的限制而不是真正的解决方案。Spring可以通过简化这些过程而节省大量时间。”
Christophe Coenraets解释了Flex与Spring集成的基本原理:
Spring的控制反转(Inversion of Control, 即IoC)的主要思想就是让容器实例化组件(并且注入其依赖)。但是在默认情况下,由Flex客户端远程访问的组件是在服务器端由Flex目的文件实例化 的。所以Flex与Spring集成的关键在于配置Flex目的文件以使其能够让Spring容器来管理实例化的Spring beans。Flex数据服务支持工厂的概念以便可以实例化这类客户化组件。工厂的作用仅仅在于向Flex目的文件提供准备好的组件实例,而不是让 Flex目的文件自己去实例化这些组件。
关于Flex与Spring、IBATIS和Cairngorm的集成,Chris Giametta说道:
我相信可以创建一个一致的、模块化的、可重用的架构。这个架构既可以支持小型应用,也可以支持非常健壮 的企业级应用。项目成功的一个关键要素在于创建这样一个架构:新人能迅速投入进去,并且很快就能上手。我觉得将Flex与Spring、iBATIS和 Cairngorm集成可以帮助我迅速构建出一个基于模式的、可重用的架构。
Sébastien Arbogast在不遗余力地发表一系列博文,以阐述如何构建全栈式Flex、BlazeDS和Spring集成解决方案。
Arbogast的这个全栈式集成,从下到上包括如下内容:JBoss作为应用服务器、MySQL作为数据存储、Hibernate完成数据访问、Spring用来构建业务层、BlazeDS作为远程服务、Flexe-genial用来构建富客户端。该系统使用Maven及flex-compiler-mojo插件进行构建。
Arbogast说:“这个项目的建立当然需要一些工作,但是——除去配置文件复制上的一些小问题外(而且这很快会得到改善)——它真的很干净,而且flex-compiler-mojo也非常棒。”
[资源]Reflector for .net framework 3.5下载
Reflector 应该是所有.Net 开发者必备的工具了, 这次重大的更新带来了很多方便和实用的特性:
1. C# 3.0/2.0 语言语法的完美反编译支持, 包括C# 3.0 的扩展方法, LINQ, Lambda, 以及C# 2.0的匿名方法等
2. "Code URL" 支持
3. 程序集浏览器的改进
4. 反编译浏览器的改进, 包括可以动态显示文档
5. 分析器的改进, 添加了“Exposed By”和“Instantiated By” 两种搜索
6. 搜索功能的改进, 包括字符串和常量搜索, 多关键字搜索
7. 资源查看器的改进
8. 更多的自定义选项和Windows Vista 的更好支持.
Reflector 下载地址:
http://www.aisto.com/roeder/dotnet/
Reflector 插件:
http://www.codeplex.com/reflectoraddins
Reflector 5.0 New Feature(PPT格式)
http://www.aisto.com/roeder/paper/reflector5.ppt
Enjoy Your Exploring Experience!~
[教程]理解Asp.Net Pages
1.动态编译
当一个ASP.NET Page被创建时,实际上创建的是一个.net类, 一个System.Web.UI.Page的实例. 页面的所有内容,包括HTML代码和Script代码,都被编译进这个.net类中.
当 有一个Request请求这个页面时,ASP.NET Framework检查被请求页面的相应的类是否存在,如果不存在则把页面编译成.net类,并且把编译了的类(assembly)存放到 Temporary Asp.Net Files这个目录中.这个文件夹一般位于
:\WINDOWS\Microsoft.NET\Framework\[version]\Temporary ASP.NET Files
当有新的请求到来时,编译过程将不在需要,先前编译好的类直接执行,并把结果返回给浏览器.
2.控件树
Asp.Net Page可以理解为是一个.Net类的源代码, 除此之外,也可以把Asp.Net Page理解为是一个控件包( a bag of controls).因为有点控件本身可能含有控件,因此更确切点一点,可以把Asp.Net Page理解为一个控件树.
例如:
<%@ Page Language="VB" Trace="true" %>2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"3
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">4
<html xmlns="http://www.w3.org/1999/xhtml" >5
<head id="Head1" runat="server">6
<title>Show Control Tree</title>7
</head>8
<body>9
<form id="form1" runat="server">10
<div>11

12
<asp:DropDownList13
id="DropDownList1"14
Runat="server">15
<asp:ListItem Text="Oranges" />16
<asp:ListItem Text="Apples" />17
</asp:DropDownList>18

19
<asp:Button20
id="Button1"21
Text="Submit"22
Runat="server" />23

24
</div>25
</form>26
</body>27
</html>28

这样一个Asp.Net Page, 它的控件树结构如下代码所示:
__Page ASP.showcontroltree_aspx
ctl02 System.Web.UI.LiteralControl
ctl00 System.Web.UI.HtmlControls.HtmlHead
ctl01 System.Web.UI.HtmlControls.HtmlTitle
ctl03 System.Web.UI.LiteralControl
form1 System.Web.UI.HtmlControls.HtmlForm
ctl04 System.Web.UI.LiteralControl
DropDownList1 System.Web.UI.WebControls.DropDownList
ctl05 System.Web.UI.LiteralControl
Button1 System.Web.UI.WebControls.Button
ctl06 System.Web.UI.LiteralControl
ctl07

Asp.Net Page中包含的所有内容都被包含进一个.Net类中, 甚至包括HTML和纯文本内容.
3.Code-Behind Pages
Asp.Net Framework允许你创建两种类型的Asp.Net Pages, 单文件Pages和双文件Pages.这两种类型到底怎么样就不再赘述.稍微来看一下code-behind是如何工作的.
在Asp.Net 1.1中,Asp.Net Framework会为表现层页面(.aspx)和code-behind文件(.cs)产生两个单独的类,这两个类之间通过继承相关联,其中表现层页面类继承code-behind类.
由于继承是一个单向的关系,因此这种方法很脆弱.所有在表现层页面中声明的控件也必须同样在code-behind文件中声明,而且属性必须也相同.否则,控件触发的事件就可能不会被code-behind文件所捕获而加以处理.
在Asp.Net 2.0中,引入了一种新的机制:Partial Class.它允许把一个类的定义分散到不同的文件中.因此你就不需要在表现层页面和code-behind文件中同时声明,两者中任何的一个声明都可以在另一个中直接使用.
5.处理页面事件
当你请求一个页面时,页面触发事件的顺序如下:
-
PreInit
-
Init
-
InitComplete
-
PreLoad
-
Load
-
LoadComplete
-
PreRender
-
PreRenderComplete
-
SaveStateComplete
-
Unload
[教程]ASP.Net MVC入门教程
Introduction
MVC应该算是一个古老的Design Pattern了,无论是在win form程序还是web程序中,它的应用都是比较广泛的。MVC也是我在学校中学习到的第一个设计模式。终于,可以在ASP.NET中应用了。本文的例子 所用的是ASP.NET MVC Preview 2,可以在这里下载。
Create a new MVC project
菜单File->New Project ->Asp.Net Web MVC Application

新创建的项目是一个完整的可以运行的Sample程序。
新创建的MVC Project和传统的Asp.net web application不同,MVC Project包含有如下四个文件夹:
- Content Folder : 这个文件夹中放一些支持文件,如CSS等。
- Controller Folder :这个文件夹中放所以的Controller文件
- Models folder : 这个文件夹存放所有的data model文件,包括:LINQ to SQL DBML文件,Entity文件
- Views folder : 存放所有的页面文件,包括master文件。Master等需要被共享访问的需要被放在一个Shared子文件夹中。
Advantages of an MVC-Based Web Application
- 把程序分为Model, View和Controller之后,更容易控制程序的复杂性
- 没有了传统的Asp.Net中的viewstate和server端的form,使得开发人员可以实现对页面的完全控制。当然也失去了viewstate和server端form带来的各种好处
- 支持测试驱动开发
Features of the ASP.NET MVC Framework
- 应用程序的业务分离,支持测试驱动开发
- 可扩展和支持插件的Framework。开发人员都可以根据自己的需要修改甚至替换ASP.NET MVC Framework的各个component,也可以以插件的形式开发自己的View Engine,URL Routing Policy等各种component。ASP.NET MVC Framework甚至支持依赖注入(Dependency Injection)和控制反转(Inversion of Control)等容器模式。
- 强大的URL-Mapping功能。使得URL地址更有意义(REST)。URL中不再包括文件扩展名。
-
对很多传统Asp.Net特性的支持。如<%=%>, user control等。
The MVC Framework and Postbacks
Asp.Net MVC 不再使用传统的Asp.Net Web Application的postback模式。取而代之的是,所有的客户端发回服务器端的request都会被映射到某一个controller类中, 这使UI logic和business logic得以分离,从而有助于提高程序的可测试性。
Understanding the MVC Project Execution Process
Request被发回服务器端之后,首先都由UrlRoutingModule对象来解析这个Request,并根据URL找到一个匹配的Router对象,之后由这个Router对象来处理这个Request。 MVC Application的处理流程:
- Initial Request: routers在Global.ascx中被添加到RouteTable中。
- Routing: UrlRoutingModule找到匹配的Router对象,决定使用哪个controller,调用哪个action。
- Map to controller: MvcRouteHandler会尝试通过routedata来创建controller的type name.
- Create Controller
- Execute Controller
[代码]Object/DataSet Relational Mapping(对象/数据集关系映射)补
using System;2
using System.Data;3
using System.Configuration;4
using System.Collections;5
using System.Web;6
using System.Web.Security;7
using System.Web.UI;8
using System.Web.UI.WebControls;9
using System.Web.UI.WebControls.WebParts;10
using System.Web.UI.HtmlControls;11

12
using IBatisNet.DataMapper;13
using System.Reflection;14

15
/// <summary>16
/// ODRM为结合ORM与DataSet,并自动根据O和DataSet生成对象,以便业务层处理17
/// </summary>18
public partial class ODRM_test : PageBase19
{20
protected void Page_Load(object sender, EventArgs e)21
{22
if (!IsPostBack)23
{24
DataSet set11 = Mapper.Instance().QueryForDataSet("SelectXTM_UserByKey_Test",UIhashtable);25
DataTable table1 = ConvertDataTable(set11, "");26
//这里为自己定义的序列化类27
cXTM_User[] objModel = new cXTM_User[table1.Rows.Count];28
//DataTable转化为序列化类数组29
for (int y = 0; y < table1.Rows.Count; y++)30
{31
objModel[y] = new cXTM_User();32
DataTableConvertObject(table1.Rows[y], objModel[y]); 33
}34
//以DataSet模式绑定35
ExDataGrid1.DataSource = table1;36
//以序列化对象模式绑定37
//ExDataGrid1.DataSource = objModel;38
ExDataGrid1.DataBind();39
}40
}41

42
protected void ExDataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)43
{44
/*45
* 该部分应用范围46
* 查询一条数据的修改,可以用objModel.UserName47
* 而不必再使用DataTable[0].Rows[0]["UserName"]的模式48
* 提高面向对象的程度,并减少业务流程部分编码49
*/50

51
if (e.Item.ItemIndex != –1)52
{53
cXTM_User objModel = new cXTM_User();54
55
//如果为DataSet填充的DataGrid56
if (e.Item.DataItem.GetType().FullName == "System.Data.DataRowView")57
{58
DataTableConvertObject((DataRow)((DataRowView)e.Item.DataItem).Row, objModel); 59
}60
//否则认为为序列化对象填充61
else 62
{63
objModel = (cXTM_User)e.Item.DataItem; 64
65
}66
}67
}68

69
#region 指定对象函数70
/// <summary>71
/// 数据集中一行DataRow转换为指定对象,并填充数据72
/// </summary>73
/// <param name="row">数据集中一行</param>74
/// <param name="objModel">指定对象</param>75
private void DataTableConvertObject(DataRow row, cXTM_User objModel)76
{77
Hashtable hTable = new Hashtable();78
hTable = DataRowConvertHashtable(row);79
Type entitytype = Type.GetType(objModel.GetType().AssemblyQualifiedName);80

81
for (int j = 0; j < objModel.Propertylist.Length; j++)82
{83
PropertyInfo propertyinfo = entitytype.GetProperty(objModel.Propertylist[j]);84
propertyinfo.SetValue(objModel, hTable[objModel.Propertylist[j]], null);85
}86
}87

88
/// <summary>89
/// 对象转换为哈希表90
/// </summary>91
/// <param name="objModel">有数据的对象</param>92
/// <returns>填充数据后的哈希表</returns>93
public Hashtable ObjectConvertHashtable(cXTM_User objModel)94
{95
Hashtable hTable = new Hashtable();96
Type entitytype = Type.GetType(objModel.GetType().AssemblyQualifiedName);97
for (int j = 0; j < objModel.Propertylist.Length; j++)98
{99
PropertyInfo propertyinfo = entitytype.GetProperty(objModel.Propertylist[j]);100
hTable.Add(objModel.Propertylist[j], propertyinfo.GetValue(objModel, null));101
}102
return hTable;103
}104

105
/// <summary>106
/// 对象转换为DataTable,并有单行DataRow107
/// </summary>108
/// <param name="objModel">有数据的对象</param>109
/// <returns></returns>110
public DataTable ObjectConvertDataTableWidthRow(cXTM_User objModel)111
{112
return ObjectConvertDataTableWidthRow(objModel, "");113
}114

115
/// <summary>116
/// 对象转换为DataTable,并有单行DataRow117
/// </summary>118
/// <param name="objModel">有数据的对象</param>119
/// <returns></returns>120
public DataTable ObjectConvertDataTableWidthRow(cXTM_User objModel, string DataMapper)121
{122
Type entitytype = Type.GetType(objModel.GetType().AssemblyQualifiedName);123
DataTable dt = new DataTable();124
if (DataMapper != "")125
{126
dt = new DataTable(DataMapper);127
}128
dt.Columns.Clear();129
for (int j = 0; j < objModel.Propertylist.Length; j++)130
{131
PropertyInfo propertyinfo = entitytype.GetProperty(objModel.Propertylist[j]);132
dt.Columns.Add(new DataColumn(objModel.Propertylist[j], propertyinfo.GetType()));133
}134
DataRow row = dt.NewRow();135
for (int j = 0; j < objModel.Propertylist.Length; j++)136
{137
PropertyInfo propertyinfo = entitytype.GetProperty(objModel.Propertylist[j]);138
row[objModel.Propertylist[j]] = propertyinfo.GetValue(objModel, null);139
}140
dt.Rows.Add(row);141

142
return dt;143
}144

145
/// <summary>146
/// 对象转换为DataTable,并有多行DataRow147
/// </summary>148
/// <param name="objModel">有数据的对象</param>149
/// <returns></returns>150
public DataTable ObjectConvertDataTableWidthRows(cXTM_User[] objModel)151
{152
return ObjectConvertDataTableWidthRows(objModel, "");153
}154

155
/// <summary>156
/// 对象转换为DataTable,并有多行DataRow157
/// </summary>158
/// <param name="objModel">有数据的对象</param>159
/// <returns></returns>160
public DataTable ObjectConvertDataTableWidthRows(cXTM_User[] objModel, string DataMapper)161
{162
Type entitytype = Type.GetType(objModel.GetType().AssemblyQualifiedName);163
DataTable dt = new DataTable();164
if (DataMapper != "")165
{166
dt = new DataTable(DataMapper);167
}168
if (objModel.Length == 0)169
{170
return dt;171
}172
dt.Columns.Clear();173
for (int j = 0; j < objModel[0].Propertylist.Length; j++)174
{175
PropertyInfo propertyinfo = entitytype.GetProperty(objModel[0].Propertylist[j]);176
dt.Columns.Add(new DataColumn(objModel[0].Propertylist[j], propertyinfo.GetType()));177
}178

179
for (int i = 0; i < objModel.Length; i++)180
{181
DataRow row = dt.NewRow();182
for (int j = 0; j < objModel[i].Propertylist.Length; j++)183
{184
PropertyInfo propertyinfo = entitytype.GetProperty(objModel[i].Propertylist[j]);185
row[objModel[i].Propertylist[j]] = propertyinfo.GetValue(objModel[i], null);186
}187
dt.Rows.Add(row);188
}189
return dt;190
}191
#endregion192

193
#region 通用函数194

195
/// <summary>196
/// 转换为DataTable197
/// </summary>198
/// <param name="Source">数据源</param>199
/// <param name="DataMember">数据表名称</param>200
public static DataTable ConvertDataTable(object Source, string DataMember)201
{202
DataTable baseTable = new DataTable();203
if (Source is DataTable)204
{205
baseTable = (DataTable)Source;206
return baseTable;207
}208
if (Source is DataSet)209
{210

211
DataSet set1 = (DataSet)Source;212
if ((set1.Tables.Count > 1) && ((DataMember == null) || (DataMember == "")))213
{214
throw new Exception("If there is more than one table in your dataset, you must define the DataMember property to specify which table to use.");215
}216
if (set1.Tables.Count < 1)217
{218
throw new Exception("There are no tables in the datasource.");219
}220
if ((DataMember != null) && (DataMember != ""))221
{222
baseTable = set1.Tables[DataMember];223
return baseTable;224
}225
else226
{227
baseTable = set1.Tables[0];228
return baseTable;229
}230

231
}232
return baseTable;233
}234

235
/// <summary>236
/// 返回DataTable为哈希表键值对237
/// </summary>238
/// <param name="SourceTable">数据行对象</param>239
/// <returns>填充后哈希表</returns>240
public static Hashtable DataRowConvertHashtable(DataRow SourceRow)241
{242
Hashtable hTable = new Hashtable();243
IList list = SourceRow.ItemArray;244
object[] tObj = new object[SourceRow.Table.Columns.Count];245

246
for (int i = 0; i < SourceRow.Table.Columns.Count; i++)247
{248
tObj[SourceRow.Table.Columns.IndexOf(SourceRow.Table.Columns[i].ColumnName)] = SourceRow.Table.Columns[i].ColumnName;249
}250

251
for (int x = 0; x < list.Count; x++)252
{253
hTable.Add(tObj[x].ToString(), list[x]);254
}255
return hTable;256
}257

258
#endregion259

260

261

262

263
}264

[问题]插入SQLServer2005中文字符乱码问题
插入条记录
发现回显的全部都是 ?????….
乱码….
仔细查看了半天
发现数据库的排序规则是德语…
修改方法:数据库属性->选项->排序规则
设置成 CHINESE_PRC_CI_AI 就可以了
[教程]log4net简明手册
常见面,却不怎么用,究其原因还是觉得太复杂了点。不过,这东西出现次数越来越频繁,也只好写点东西,以备后用。本文仅对 Log4net 的使用做个简要说明,所有涉及到扩展和开发的部分一概忽略。
使用 Log4net,需要熟悉的东东有 Logger、Appender 以及 Layout。Logger 是日志记录器,我们使用其相关方法来完成日志记录;Appender 用于设置日志的存储方式和位置,Logger 的配置中会绑定一个或多个 Appender;Layout 关联具体的 Appender,用于设置日志字符串的格式。
1. Logger
所有的记录器都必须实现 ILog 接口,该接口提供日志记录所需的大量方法。
public interface ILog : ILoggerWrapper
{
void Debug(…);
void Error(…);
void Fatal(…);
void Info(…);
void Warn(…);
bool IsDebugEnabled { get; }
bool IsErrorEnabled { get; }
bool IsFatalEnabled { get; }
bool IsInfoEnabled { get; }
bool IsWarnEnabled { get; }
}
通常情况下,我们通过 LogManager.GetLogger() 来获取一个记录器。LogManager 内部维护一个 hashtable,保存新创建 Logger 引用,下次需要时直接从 hashtable 获取其实例。
ILog log = LogManager.GetLogger(this.GetType());
log.Debug(“aaaaaaaaaaaaaaa”);
所有 Logger 的参数设置都直接或间接继承自 root,其继承关系类似 namespace。比如,名为 “MyLogger.X.Y” 参数设置继承自 “MyLogger.X”。当我们创建 “MyLooger.X.Y” 记录器时,会在配置文件找该名称的记录器设置,如果没找到,则按继承关系向上查找,直到 root。因此,在创建 Logger 时,我们通常使用类型名称做为记录器的名字,缺省情况下,它会使用 root 或某一个父配置,但在需要的时候,我们随时可以为具体的类型添加一个更加 “详细” 的配置。
在创建 Logger 设置时,需要注意 “level” 参数。Log4net 允许我们通过该参数调整日志记录级别,只有高于或等于该级别的日志才会被记录下来。比如在代码调试阶段,我们可能希望记录所有的信息,而在部署阶段,我们只希望记录级别更高的错误信息。这个参数的好处是允许我们在不修改代码的前提下,随时调整记录级别。
(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低)
“appender-ref” 参数用于绑定一个或多个具体的 Appender。
2. Appender / Layout
Log4net 提供了大量的 Appender,最常用的包括 AdoNetAppender、AspNetTraceAppender、ConsoleAppender、FileAppender、 OutputDebugStringAppender。每种 Appender 都有特定一些参数,使用时直接从 《Log4net 手册》的示例中拷贝过去,就OK了。(代码摘自 Log4net 手册)
(1) AspNetTraceAppender
(2) ConsoleAppender
(3) OutputDebugStringAppender
(4) FileAppender
有关 Layout 详细信息,请参考 Log4net 相关文档,本文不做详述。
3. Configuration
Log4net 的配置方式十分灵活,即可以写到应用程序配置文件中,也可以使用独立配置文件。同时它还提供了监测配置文件变化的功能,这样我们随时可以调整配置,而无须重启应用程序。
(1) 使用 app.config / web.config
app.config / web.config
使用代码初始化配置。
log4net.Config.XmlConfigurator.Configure();
(2) 使用自定义配置文件
test.log4net
使用代码初始化配置。
log4net.Config.XmlConfigurator.Configure(new FileInfo(“test.log4net”));
使用 XmlConfigurator.ConfigureAndWatch() 方法除了初始化配置外,还会监测配置文件的变化,一旦发生修改,将自动刷新配置。
(3) XmlConfiguratorAttribute
我们还可以使用 XmlConfiguratorAttribute 代替 XmlConfigurator.Config()/ConfigureAndWatch(),ConfiguratorAttribute 用于定义与 Assembly 相关联的配置文件名。
方式1: 关联到 test.log4net,并监测变化。
[assembly: log4net.Config.XmlConfigurator(ConfigFile=”test.log4net”, Watch=true)]
方式2: 关联到 test.exe.log4net (或 test.dll.log4net,文件名前缀为当前程序集名称),并监测变化。
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension=”log4net”, Watch=true)]
[教程]log4net配置与应用
log4net 配置与应用
log4net是apache组织开发的日志组件, 同其姐妹log4j一样, 是一个开源项目. 可以以插件的形式应用在你的系统中. 下面仅说明如何应用在web forms项目中. 做为主要的日志输出组件.
1. 首先你应该下载log4net.dll并引入到你的项目References中.
2. 需要修改你的global.asa.cs. 配置application对象启动的时候加载log4net配置. 这一步是不可以缺少的.
{
log4net.Config.DOMConfigurator.Configure();
}
3. 可以看到上面的代码没有参数. 可见是载入了缺省配置. 该配置必须设置于web.config中.
在web.cofig根节点 configuration 中加入如下section:
<configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections>
4.该 config section 声明了名为 log4net 的另外一个config section. 后者必须位于web.config根节点 configuration 下: 以下是一个sample:
<log4net debug="false">
<appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
<param name="File" value="XxxxApplication.log.txt" />
<param name="datePattern" value="MM-dd HH:mm" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<appender name="HttpTraceAppender" type="log4net.Appender.ASPNetTraceAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="_LogData\Log.txt" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="10" />
<param name="MaximumFileSize" value="5MB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
5. 以上定义了多个appender. 简单来说, 每一个 appender 都是一种输出介质.
6. root节点指定了选用的 appender. 本例选用了LogFileAppender. (文本文件输出). 在Appender定义中定义了输出的格式. 和目标文本文件所在位置. (起始位置是应用程序根目录. (web.config所在目录).
7. 到目前位置就配置好了log4net. 可以在我们的应用中直接使用了.
8. 以下说明应用方法:
要输出日志, 必须首先得到带有一个别名的logger.
使用以下命令
(C#):
log4net.ILog Logger logger = log4net.LogManager.GetLogger(this.GetType());
(可以直接使用GetType得到当前类名)
之后调用
logger.Info(string message);
logger.Error(string message);
logger.Debug(string message);
即可输出日志.
调试后可查找应用程序根目录下是否已经自动创建XxxxxApplication.log.txt文本文件.以及是否正确输出了日志.
log4net是一个非常完善的日志组件. 有着强大的可配置性. 有助于提高开发效率.
关于log4net的配置. 可参考apache组织的官方文档位于
http://logging.apache.org/log4net
[问题]未将对象引用设置到对象的实例
最近编写程序进行单元测试时发现提示:
“未将对象引用设置到对象的实例”的错误
搜索了一下网上的答案,还是没有好的结果,不过我将提示的string变量进行了赋值,问题解决了,大概是因为没有对变量进行初始化,造成使用时空对象引用的问题。
Mikel

