TheBeerHouse 系列二:web.config的魅力
这个跟以前~~介绍过的Web设置 类似,只是这里的Web设置更好点- -先看下web.config片断
<theBeerHouse defaultConnectionStringName="LocalSqlServer">.....</theBeerHouse>这个是跟上面name对应的节点Web设置也有详细说明~~不废话~~首先看看类图然后再分析下哪里不同咯
说明下:凡是有对应类的属性都是嵌套节点哦
让我来看看TheBeerHouseSection类的定义- -注意看~~有注释懒得打了~~
Ok--这就是主要的节点结构.让我们继续往下走:
上面这段代码有意思,他的作用是结合权限验证的如果没有经过权限验证则定位到某某页,其实我更倾向于下面这样写利用HttpHandler来自动捕捉
public class Bt : IHttpHandlerFactory
{//其实就是HttpHandler{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string sendToUrl = url; //地址栏里面的地址
System.Collections.Generic.List<string> UrlSqlit = new System.Collections.Generic.List<string>();
UrlSqlit.AddRange(url.Split('/'));
string filePath = pathTranslated;
string sendToURLString;
if(UrlSqlit[UrlSqlit.Count-1]=="Admin.aspx")
{
if(Page.User.Identity.IsAuthenticated&&Roles.IsUserInRole(Page.User.Identity,"Admin")
{
sendToURLString= "~/Admin.aspx"; //真正要访问的页面
}else
{
sendToURLString="~/AccessDenied.aspx";
}
}
string queryString =""; //参数。比如?id=123
//这句最重要了。转向了。
context.RewritePath(sendToURLString, String.Empty, queryString);
//这个还没有弄明白:)---返回新的编译实例
return PageParser.GetCompiledPageInstance(url, filePath, context);
}
//---------------------------------使工厂可以重用现有的处理程序实例。
public virtual void ReleaseHandler(IHttpHandler handler)
{
}
}
这是配置~文件
---跑题了我们继续-说说Web事件~`首先看个类
--接下来就是配置~~都有注释的慢慢看~~
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<configSections>
<section name="theBeerHouse" type="MB.TheBeerHouse.TheBeerHouseSection, __code"/>
</configSections>
<theBeerHouse defaultConnectionStringName="LocalSqlServer">
<contactForm mailTo="thebeerhouse@wrox.com"/>
<!--默认显示商品的数量-->
<articles pageSize="10" />
<polls archiveIsPublic="true" votingLockByIP="false" />
<newsletters fromEmail="thebeerhouse@wrox.com" fromDisplayName="TheBeerHouse" />
<forums threadsPageSize="8" hotThreadPosts="10" bronzePosterPosts="10" silverPosterPosts="20" goldPosterPosts="50" />
<store sandboxMode="true" businessEmail="thebeerhouse@wrox.com" />
</theBeerHouse>
开始- -分析首先是 <section name="theBeerHouse" type="MB.TheBeerHouse.TheBeerHouseSection, __code"/>Web设置 讲过了~~就是对应一个类.<configSections>
<section name="theBeerHouse" type="MB.TheBeerHouse.TheBeerHouseSection, __code"/>
</configSections>
<theBeerHouse defaultConnectionStringName="LocalSqlServer">
<contactForm mailTo="thebeerhouse@wrox.com"/>
<!--默认显示商品的数量-->
<articles pageSize="10" />
<polls archiveIsPublic="true" votingLockByIP="false" />
<newsletters fromEmail="thebeerhouse@wrox.com" fromDisplayName="TheBeerHouse" />
<forums threadsPageSize="8" hotThreadPosts="10" bronzePosterPosts="10" silverPosterPosts="20" goldPosterPosts="50" />
<store sandboxMode="true" businessEmail="thebeerhouse@wrox.com" />
</theBeerHouse>
<theBeerHouse defaultConnectionStringName="LocalSqlServer">.....</theBeerHouse>这个是跟上面name对应的节点Web设置也有详细说明~~不废话~~首先看看类图然后再分析下哪里不同咯
说明下:凡是有对应类的属性都是嵌套节点哦
让我来看看TheBeerHouseSection类的定义- -注意看~~有注释懒得打了~~
TheBeerHouseSection
其他的部分,只写一个~~不占用版面了~~~
/// <summary>
/// 配置电子邮件
/// </summary>
public class ContactFormElement : ConfigurationElement
{
[ConfigurationProperty("mailSubject", DefaultValue="Mail from TheBeerHouse: {0}")]
public string MailSubject
{
get { return (string)base["mailSubject"]; }
set { base["mailSubject"] = value; }
}
[ConfigurationProperty("mailTo", IsRequired=true)]
public string MailTo
{
get { return (string)base["mailTo"]; }
set { base["mailTo"] = value; }
}
[ConfigurationProperty("mailCC")]
public string MailCC
{
get { return (string)base["mailCC"]; }
set { base["mailCC"] = value; }
}
}
/// 配置电子邮件
/// </summary>
public class ContactFormElement : ConfigurationElement
{
[ConfigurationProperty("mailSubject", DefaultValue="Mail from TheBeerHouse: {0}")]
public string MailSubject
{
get { return (string)base["mailSubject"]; }
set { base["mailSubject"] = value; }
}
[ConfigurationProperty("mailTo", IsRequired=true)]
public string MailTo
{
get { return (string)base["mailTo"]; }
set { base["mailTo"] = value; }
}
[ConfigurationProperty("mailCC")]
public string MailCC
{
get { return (string)base["mailCC"]; }
set { base["mailCC"] = value; }
}
}
Ok--这就是主要的节点结构.让我们继续往下走:
<authentication mode="Forms">
<forms cookieless="AutoDetect" loginUrl="~/AccessDenied.aspx" name="TBHFORMAUTH"/>
</authentication>
<forms cookieless="AutoDetect" loginUrl="~/AccessDenied.aspx" name="TBHFORMAUTH"/>
</authentication>
上面这段代码有意思,他的作用是结合权限验证的如果没有经过权限验证则定位到某某页,其实我更倾向于下面这样写利用HttpHandler来自动捕捉
public class Bt : IHttpHandlerFactory
{//其实就是HttpHandler{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string sendToUrl = url; //地址栏里面的地址
System.Collections.Generic.List<string> UrlSqlit = new System.Collections.Generic.List<string>();
UrlSqlit.AddRange(url.Split('/'));
string filePath = pathTranslated;
string sendToURLString;
if(UrlSqlit[UrlSqlit.Count-1]=="Admin.aspx")
{
if(Page.User.Identity.IsAuthenticated&&Roles.IsUserInRole(Page.User.Identity,"Admin")
{
sendToURLString= "~/Admin.aspx"; //真正要访问的页面
}else
{
sendToURLString="~/AccessDenied.aspx";
}
}
string queryString =""; //参数。比如?id=123
//这句最重要了。转向了。
context.RewritePath(sendToURLString, String.Empty, queryString);
//这个还没有弄明白:)---返回新的编译实例
return PageParser.GetCompiledPageInstance(url, filePath, context);
}
//---------------------------------使工厂可以重用现有的处理程序实例。
public virtual void ReleaseHandler(IHttpHandler handler)
{
}
}
>
<httpHandlers><!--verb是处理的请求类型*是所有,GET,POST, PATH=处理的类型,typehttpHandLers-->
<add verb="*" path="*.aspx" type="Bt"/>
</httpHandlers>
<httpHandlers><!--verb是处理的请求类型*是所有,GET,POST, PATH=处理的类型,typehttpHandLers-->
<add verb="*" path="*.aspx" type="Bt"/>
</httpHandlers>
---跑题了我们继续-说说Web事件~`首先看个类
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Management;
namespace MB.TheBeerHouse
{
public abstract class WebCustomEvent : WebBaseEvent
{
/// <summary>
/// </summary>
/// <param name="message">引发的事件的说明。</param>
/// <param name="eventSource">引发事件的对象。</param>
/// <param name="eventCode">与该事件关联的代码。实现自定义事件时,事件代码必须大于WebExtendedBase。</param>
public WebCustomEvent(string message, object eventSource, int eventCode)
: base(message, eventSource, eventCode) { }
}
public class RecordDeletedEvent : WebCustomEvent
{
private const int eventCode = WebEventCodes.WebExtendedBase + 10;//自定义WebEventCodes.WebExtendedBase事件必须大于
private const string message = "The {0} with ID = {1} was deleted by user {2}.";//这里做的好动静结合太极拳的味道
public RecordDeletedEvent(string entity, int id, object eventSource)//HttpContext.Current.User.Identity.Name获取当前用户的名称
: base(string.Format(message, entity, id, HttpContext.Current.User.Identity.Name), eventSource, eventCode)
{ }
}
}
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Management;
namespace MB.TheBeerHouse
{
public abstract class WebCustomEvent : WebBaseEvent
{
/// <summary>
/// </summary>
/// <param name="message">引发的事件的说明。</param>
/// <param name="eventSource">引发事件的对象。</param>
/// <param name="eventCode">与该事件关联的代码。实现自定义事件时,事件代码必须大于WebExtendedBase。</param>
public WebCustomEvent(string message, object eventSource, int eventCode)
: base(message, eventSource, eventCode) { }
}
public class RecordDeletedEvent : WebCustomEvent
{
private const int eventCode = WebEventCodes.WebExtendedBase + 10;//自定义WebEventCodes.WebExtendedBase事件必须大于
private const string message = "The {0} with ID = {1} was deleted by user {2}.";//这里做的好动静结合太极拳的味道
public RecordDeletedEvent(string entity, int id, object eventSource)//HttpContext.Current.User.Identity.Name获取当前用户的名称
: base(string.Format(message, entity, id, HttpContext.Current.User.Identity.Name), eventSource, eventCode)
{ }
}
}
--接下来就是配置~~都有注释的慢慢看~~
<healthMonitoring heartbeatInterval="10800" >//针对运行状况监视配置应用程序,必选的 TimeSpan 属性。
//heartbeatInterval指定时间间隔,即引发 WebHeartbeatEvent 事件的频率(以秒为单位)。 默认值为 "00:00:00",它表示不引发 WebHeartbeatEvent 事件。
<providers>
<remove name="SqlWebEventProvider" />
<add name="SqlWebEventProvider" connectionStringName="LocalSqlServer"//buffer定义提供程序的缓冲功能。
buffer="false" bufferMode="Notification" maxEventDetailsLength="1073741823"//bufferMode定义提供程序的缓冲功能。
type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
<eventMappings>//可选的元素。将事件友好名称映射到相关的事件类型。
<add name="TBH Events" type="MB.TheBeerHouse.WebCustomEvent, MB.TheBeerHouse.CustomEvents" />
</eventMappings>
<rules>
<clear />//就是可以触发检测的程序配置--SqlWebEventProvider这个是值得记录到Sql中--记录Window到日志中--EventLogWebEventProvider
<add name="TBH Events" eventName="TBH Events" provider="SqlWebEventProvider" profile="Critical" />
<add name="All Errors" eventName="All Errors" provider="SqlWebEventProvider" profile="Critical" />
<add name="Failure Audits" eventName="Failure Audits" provider="SqlWebEventProvider" profile="Critical" />
<add name="Heartbeats" eventName="Heartbeats" provider="SqlWebEventProvider" profile="Critical" />
</rules>
</healthMonitoring>
//heartbeatInterval指定时间间隔,即引发 WebHeartbeatEvent 事件的频率(以秒为单位)。 默认值为 "00:00:00",它表示不引发 WebHeartbeatEvent 事件。
<providers>
<remove name="SqlWebEventProvider" />
<add name="SqlWebEventProvider" connectionStringName="LocalSqlServer"//buffer定义提供程序的缓冲功能。
buffer="false" bufferMode="Notification" maxEventDetailsLength="1073741823"//bufferMode定义提供程序的缓冲功能。
type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
<eventMappings>//可选的元素。将事件友好名称映射到相关的事件类型。
<add name="TBH Events" type="MB.TheBeerHouse.WebCustomEvent, MB.TheBeerHouse.CustomEvents" />
</eventMappings>
<rules>
<clear />//就是可以触发检测的程序配置--SqlWebEventProvider这个是值得记录到Sql中--记录Window到日志中--EventLogWebEventProvider
<add name="TBH Events" eventName="TBH Events" provider="SqlWebEventProvider" profile="Critical" />
<add name="All Errors" eventName="All Errors" provider="SqlWebEventProvider" profile="Critical" />
<add name="Failure Audits" eventName="Failure Audits" provider="SqlWebEventProvider" profile="Critical" />
<add name="Heartbeats" eventName="Heartbeats" provider="SqlWebEventProvider" profile="Critical" />
</rules>
</healthMonitoring>
//--------------。与内置的 ASP.NET 运行状况监视事件不同的是,自定义事件必须显式引发。
要引发自定义事件必须
RecordDeletedEvent swre =new RecordDeletedEvent ("Heartbeats", this, myCode);//--参数1是eventName
// --运行这个引发自定义事件
swre.Raise();