在上一篇文章的Controller中我们已经看到了,是怎么使用TYExceptionService进行异常的处理与日志记录,本篇文章具体介绍一下TYExceptionService是如使用Enterprise Library 5.0详细的实现。
因为我们的这个系统是面向接口编程的,所以也需要把TYExceptionService注入到Controller,所以也需要一个ITYExceptionService的接口。
ITYExceptionService异常处理服务接口
这个接口中只有一个方法HandleException,接收一个异常对象,一个Dictionary来存非法的属性和一个字符串message自定义的异常信息。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace TYStudioDemo.Interfaces
- {
- public interface ITYExceptionService
- {
- string HandleException(Exception exception, Dictionary<string, object> parms, string message);
- }
- }
实现类TYExceptionService
详细的说明见代码中的注释
- using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.Text;
- using System.Threading.Tasks;
- using TYStudioDemo.Interfaces;
- using TYStudioDemo.Commons;
- namespace TYStudioDemo.Services
- {
- public class TYExceptionService : ITYExceptionService
- {
- public string HandleException(Exception exception, Dictionary<string, object> parms, string message)
- {
- //穿件我们自己定义的异常类
- TYException tyException = new TYException(message, exception);
- //建立一个StackFrame
- StackFrame frame = new StackFrame(1, true);
- //记录抛出异常的文件名,方法名和,行号
- tyException.SetErrorProperty(TYException.CurrentFilename, frame.GetFileName());
- tyException.SetErrorProperty(TYException.CurrentFunction, frame.GetMethod().Name);
- tyException.SetErrorProperty(TYException.CurrentLineNumber, frame.GetFileLineNumber().ToString());
- // parameters, if present
- if (parms != null)
- {
- foreach (KeyValuePair<string, object> parm in parms)
- {
- if (parm.Value != null)
- {
- tyException.SetErrorProperty(parm.Key, parm.Value.ToString());
- }
- }
- }
- //使用EntityPrise Library记录异常信息,TYStudioPolicy配置在Web.Config文件中
- ExceptionPolicy.HandleException(tyException, "TYStudioPolicy");
- //返回有好的错误信息到页面
- return tyException.Message;
- }
- }
- }
自定义异常类TYException
见代码注释:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.Text;
- using System.Threading.Tasks;
- namespace TYStudioDemo.Commons
- {
- [Serializable]
- public class TYException : Exception
- {
- //用来记录抛异常的方法,文件名和行号
- public static string CurrentFunction = "Function";
- public static string CurrentFilename = "Filename";
- public static string CurrentLineNumber = "Line Number";
- //定义够方法,调用Exception基类的构造方法
- public TYException() : base() { }
- public TYException(string message) : base(message) { }
- public TYException(string message, System.Exception inner) : base(message, inner) { }
- protected TYException(SerializationInfo info, StreamingContext context) : base(info, context) { }
- //键值对的构造方法
- //把键值对存入Data,最终通过Enterprise library text foramtter存入数据库中
- public TYException(string message, Exception inner, IDictionary<string, string> props)
- : base(message, inner)
- {
- foreach (KeyValuePair<string, string> entry in props)
- if (!String.IsNullOrEmpty(entry.Key) && props[entry.Key] != null)
- Data[entry.Key] = entry.Key;
- }
- //获得错误属性值
- public string GetErrorProperty(string key)
- {
- return (Data[key] == null) ? string.Empty : Data[key].ToString();
- }
- //添加错误属性值
- public void SetErrorProperty(string key, string value)
- {
- if (!String.IsNullOrEmpty(key) && value != null)
- Data[key] = value;
- }
- }
- }
TYStudioDemo.Commons工程,我移除最开始Utilities工程,用这个工程代替了。这里主要放一些公共的类,或者一些工具类。TYException就放在了这里,当然你有好的地方,完全可以放到其他工程。
Enterprise Library配置Web.Config
具体配置内容是由Enterprise Library工具生成的,首先你需要安装Enterprise Library 5.0,下载地址http://entlib.codeplex.com/ 。安装完成之后找到安装目录下的C:\Program Files (x86)\Microsoft Enterprise Library 5.0\Bin\EntLibConfig.exe,具体的怎么配置规则不做介绍,可以去网上搜索资料。这里给出一个本系统配置成功之后的截图,和相应的Web.Config代码。点击查看大图
Web.Config文件代码:
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- For more information on how to configure your ASP.NET application, please visit
- http://go.microsoft.com/fwlink/?LinkId=169433
- -->
- <configuration>
- <configSections>
- <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
- <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
- <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
- <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
- </configSections>
- <loggingConfiguration name="" tracingEnabled="true" defaultCategory="Category">
- <listeners>
- <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- databaseInstanceName="TYStudioLoggingConnectionString" writeLogStoredProcName="WriteLog"
- addCategoryStoredProcName="AddCategory" formatter="Text Formatter"
- traceOutputOptions="None" />
- </listeners>
- <formatters>
- <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- template="Exception Details:
{dictionary({key} - {value}{newline})} 
Message: {message}{newline}
{newline}
Timestamp: {timestamp}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}"
- name="Text Formatter" />
- </formatters>
- <categorySources>
- <add switchValue="All" name="Category">
- <listeners>
- <add name="Database Trace Listener" />
- </listeners>
- </add>
- </categorySources>
- <specialSources>
- <allEvents switchValue="All" name="All Events">
- <listeners>
- <add name="Database Trace Listener" />
- </listeners>
- </allEvents>
- <notProcessed switchValue="All" name="Unprocessed Category">
- <listeners>
- <add name="Database Trace Listener" />
- </listeners>
- </notProcessed>
- <errors switchValue="All" name="Logging Errors & Warnings">
- <listeners>
- <add name="Database Trace Listener" />
- </listeners>
- </errors>
- </specialSources>
- </loggingConfiguration>
- <exceptionHandling>
- <exceptionPolicies>
- <add name="TYStudioPolicy">
- <exceptionTypes>
- <add name="All Exceptions" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- postHandlingAction="None">
- <exceptionHandlers>
- <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
- logCategory="Category" eventId="100" severity="Error" title="Enterprise Library Exception Handling"
- formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
- priority="0" />
- </exceptionHandlers>
- </add>
- </exceptionTypes>
- </add>
- </exceptionPolicies>
- </exceptionHandling>
- <connectionStrings>
- <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-TYStudioDemo.WebUI-20130331202950;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-TYStudioDemo.WebUI-20130331202950.mdf"
- providerName="System.Data.SqlClient" />
- <add name="TYEntities" connectionString="metadata=res://*/TYEntities.csdl|res://*/TYEntities.ssdl|res://*/TYEntities.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=NORTHWND;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework""
- providerName="System.Data.EntityClient" />
- <add name="TYStudioLoggingConnectionString" connectionString="Data Source=localhost;Integrated Security=True;Initial Catalog=TYStudio_Logging;Persist Security Info=True;MultipleActiveResultSets=True"
- providerName="System.Data.SqlClient" />
- </connectionStrings>
- <appSettings>
- <add key="webpages:Version" value="2.0.0.0" />
- <add key="webpages:Enabled" value="false" />
- <add key="PreserveLoginUrl" value="true" />
- <add key="ClientValidationEnabled" value="true" />
- <add key="UnobtrusiveJavaScriptEnabled" value="true" />
- </appSettings>
- <system.web>
- <compilation debug="true" targetFramework="4.5" />
- <httpRuntime targetFramework="4.5" />
- <authentication mode="Forms">
- <forms loginUrl="~/Account/Login" timeout="2880" />
- </authentication>
- <pages>
- <namespaces>
- <add namespace="System.Web.Helpers" />
- <add namespace="System.Web.Mvc" />
- <add namespace="System.Web.Mvc.Ajax" />
- <add namespace="System.Web.Mvc.Html" />
- <add namespace="System.Web.Optimization" />
- <add namespace="System.Web.Routing" />
- <add namespace="System.Web.WebPages" />
- <add namespace="TYStudioDemo.DTO" />
- </namespaces>
- </pages>
- </system.web>
- <system.webServer>
- <validation validateIntegratedModeConfiguration="false" />
- <handlers>
- <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
- <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
- <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
- <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
- <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
- <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
- </handlers>
- </system.webServer>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
- <entityFramework>
- <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
- <parameters>
- <parameter value="v11.0" />
- </parameters>
- </defaultConnectionFactory>
- </entityFramework>
- </configuration>
代码上的全都配置好了,现在该是创建数据库的时候了,在安装Enterprise Library的时候,会提示你安装Source选择安装,安装完成之后,我们可以在里面找到数据库的sql文件。天屹在下面的目录里找到了数据库文件,C:\Users\Administrator\Documents\EntLib50Src\Blocks\Logging\Src\DatabaseTraceListener\Scripts\LoggingDatabase.sql,前面系统documents路径根据自己的机器各不相同,自己修改一下。
不知道什么原因,这个默认的数据库和我们的系统不兼容,两个存储过程有问题AddCategory和WriteLog,这两存储过程的参数和mvc内置的有一些出入,所以需要修改一下,下面列出修改的存储过程sql:
AddCategory
- USE [TYStudio_Logging]
- GO
- /****** Object: StoredProcedure [dbo].[AddCategory] Script Date: 04/06/2013 14:46:20 ******/
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- ALTER PROCEDURE [dbo].[AddCategory]
- -- Add the parameters for the function here
- @categoryName nvarchar(64),
- @logID int
- AS
- BEGIN
- SET NOCOUNT ON;
- DECLARE @CatID INT
- SELECT @CatID = CategoryID FROM Category WHERE CategoryName = @categoryName
- IF @CatID IS NULL
- BEGIN
- INSERT INTO Category (CategoryName) VALUES(@categoryName)
- SELECT @CatID = @@IDENTITY
- END
- EXEC InsertCategoryLog @CatID, @logID
- RETURN @CatID
- END
WriteLog
- USE [TYStudio_Logging]
- GO
- /****** Object: StoredProcedure [dbo].[WriteLog] Script Date: 04/06/2013 14:48:27 ******/
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- /****** Object: Stored Procedure dbo.WriteLog Script Date: 10/1/2004 3:16:36 PM ******/
- ALTER PROCEDURE [dbo].[WriteLog]
- (
- @eventID int,
- @priority int,
- @severity nvarchar(32),
- @title nvarchar(256),
- @timestamp datetime,
- @machineName nvarchar(32),
- @AppDomainName nvarchar(512),
- @ProcessID nvarchar(256),
- @ProcessName nvarchar(512),
- @ThreadName nvarchar(512),
- @Win32ThreadId nvarchar(128),
- @message nvarchar(1500),
- @formattedmessage ntext,
- @LogId int OUTPUT
- )
- AS
- INSERT INTO [Log] (
- EventID,
- Priority,
- Severity,
- Title,
- [Timestamp],
- MachineName,
- AppDomainName,
- ProcessID,
- ProcessName,
- ThreadName,
- Win32ThreadId,
- Message,
- FormattedMessage
- )
- VALUES (
- @eventID,
- @priority,
- @severity,
- @title,
- @timestamp,
- @MachineName,
- @AppDomainName,
- @ProcessID,
- @ProcessName,
- @ThreadName,
- @Win32ThreadId,
- @message,
- @formattedmessage)
- SET @LogId = @@IDENTITY
- RETURN @LogId
如果你先麻烦天屹的下篇文章会对整系统做一个总结,并且提供整个系统成型的源代码下载,系统的Commons工程里面会有Logging数据库的备份,你恢复一下也是可以的。
Logging数据库异常信息:
最后让我们来看一眼异常被记录到Logging数据库中的样子吧,这里面有详细的异常信息,还有我们自定义的异常信息,一目了然,当然Enterprise Library也提供出现异常发送邮件的功能,你只需要到Web.Config添加相应的配置就可以了,这样出现异常会第一时间发送到你指定的邮件。
到这里异常处日志记录处理就完成了。
下篇文章天屹将提供整个系统的代码下载,敬请期待。
博主,你好,我也想制作一个自己的博客网站,正在学习asp.net mvc 和js。
想自己做一个网站,想得到一些指教,谢谢
我的博客是使用WordPress建立起来的,挺简单的。你可以加我qq,这里回复不方便。416362007