EntLib的异常处理应用程序块是一个很好的异常处理框架,它让我们可以通过配置来定义异常处理策略。ASP.NET MVC是一个可扩展的开发框架。在本文中,我将通过扩展与EntLib集成,并提供一个完整的异常处理解决方案。
一、基本异常处理策略
让我们首先讨论我们的解决方案采用的异常处理策略:
对于执行控制器的Action方法引发的异常,我们将根据指定的配置策略进行处理。我们可以采用常见的异常处理方法,如日志记录、异常替换和封装。
对于已处理的异常,如果异常处理策略规定需要抛出,将自动重定向到与异常类型匹配的错误页面。我们将维护异常类型和错误视图之间的匹配关系;
对于已处理的异常,如果异常处理策略规定不需要抛出,则执行与当前Action操作匹配的错误处理Action进行处理。异常处理Action方法默认采用“On{Action}Error”的命名规则,当前上下文绑定异常处理操作方法的参数。除了第二次,我们将设置当前模型状态的错误信息;
如果用户没有定义相应的异常处理操作,异常处理仍然采用错误页面重定向方法。
其次,通过自定义操作处理异常
为了让读者深刻理解上面介绍的异常处理页面,我们将给出一个示例演示。此示例用于模拟用户登录。我们定义了以下模型,它只包含两个属性:用户名和密码:登录信息模型。
命名空间Artech。Mvc.ExceptionHandling.Models {公共类LoginInfo {[Display(Name=' User Name ')][必选(error message=' User Name is manadatory!')]公共字符串UserName { get设置;}[显示(名称='密码')][数据类型(数据类型。密码)][必需(错误消息='密码是管理的!')]公共字符串Password { get设置;}}}我们定义了以下AccountController,它是我们定制的BaseController的子类。AccountController在构造时调用基类构造函数,指定的参数表示异常处理策略的配置名。SignIn方法表示用于“登录”的操作,而OnSignInError表示与该操作对应的异常处理操作。如果在登录操作中抛出的异常在处理后不需要抛出,将调用OnSignInError,此时已经为ModelState设置了相应的错误消息。
公共类account controller base controller { public account controller()base(' my policy '){ } public action result sign in(){ return View(new LoginInfo());}[httpset]public action result sign in(LoginInfo LoginInfo){ if(!ModelState。IsValid) {返回这个。视图(新登录信息{用户名=登录信息。UserName });} if (loginInfo。用户名!='Foo') {抛出新的invalidUserNameException();} if (loginInfo。密码!='password') {抛出新的usernamepasswordnatmatcheexception();} ViewBag。消息=“身份验证成功!”;归还这个。视图(新登录信息{用户名=登录信息。UserName });} public action result OnSignInError(字符串用户名){返回此。视图(新登录信息{用户名=用户名});}}在SignIn操作方法中具体定义的认证逻辑如下:如果用户名不是“Foo”,抛出InvalidUserNameException异常;如果密码不是“password”,将引发usernamepasswordnatmatchexception异常。以下是登录操作对应的视图定义:
@模特阿尔特奇.MVC。异常处理。模特。logininfo @ { viewpag .Title='登录;} @Html .ValidationSummary()@ if(viewpag .消息!=null){ @ viewpag .消息} @使用(Html .begin inform()){ @ Html .EditorForModel()输入类型="提交"值="登录"/}在帐户控制器初始化时指定的异常处理策略"我的策略"定义在如下的配置中。我们专门针对登录操作方法抛出的无效用户名异常和usernamepasswordnatmatchexception进行了处理,而ErrorMessageSettingHandler是我们自定义的异常处理器,它仅仅用于设置错误消息。如下面的代码片断所示,如果上述的这两种类型的异常被抛出,最终的错误消息会被指定为"用户名不存在!"和"用户名与密码不匹配!"。
异常处理异常策略添加名称='myPolicy '异常类型添加名称=' InvalidUserNameException '类型='Artech .MVC。异常处理。模特。无效用户名异常,Artech .MVC。“异常处理”后处理操作=“无”异常处理程序添加名称='ErrorMessageSettingHandler '类型='Artech .MVC。异常处理。ErrormessageSettingHandler,Artech .MVC。异常处理“错误消息=”用户名不存在!'//异常处理程序/add add name=' usernamepasswordnatmatcheexception ' type=' Artech .MVC。异常处理。模特。usernamepasswordnmatchexception,Artech .MVC。“异常处理”后处理操作=“无”异常处理程序添加名称='ErrorMessageSettingHandler '类型='Artech .MVC。异常处理。ErrormessageSettingHandler,Artech .MVC。异常处理“错误消息=”用户名与密码不匹配!'//异常句柄/添加/异常类型/添加/异常策略/异常句柄现在我们通过路由映射将帐户控制器和符号设置为默认控制器和行动后,开启我们的应用程序。在输入错误的用户名和错误明码的情况下在有效性摘要中将自动得到相应的错误消息。
三、通过配置的错误视图处理异常
在上面的配置中,针对无效用户名异常和usernamepasswordnatmatchexception这两种异常类型的配置策略都将后处理操作属性设置为"无",意味着不会将原来的异常和处理后的异常进行重新抛出。现在我们将该属性设置为"抛出新异常",意味着我们会将处理后的异常重新抛出来。
异常处理异常策略添加名称='myPolicy '异常类型添加名称=' InvalidUserNameException '类型='Artech .MVC。异常处理。模特。无效用户名异常,Artech .MVC。异常处理'后处理操作=' thrownew exception '.添加名称=' usernamepasswordnatmatchexception '类型='Artech .MVC。异常处理。模特。usernamepasswordnmatchexception,Artech .MVC。异常处理'后处理操作=' thrownew exception './add/异常类型/add/异常策略/异常处理按照我们上面的异常处理策略,在这种情况下我们将采用"错误页面"的方式来进行异常处理。也HandleErrorAttribute的处理方式类似,我们支持异常类型和错误视图之间的匹配关系,而这是通过类似于如下的配置来定义的。值得一提的是,这里的异常类型是经过处理后重新抛出的异常。
artech.exceptionHandling添加异常类型='Artech .MVC。异常处理。模特。无效用户名异常,Artech .MVC。异常处理'错误视图=' InvalideUserNameError '/添加异常类型=' Artech .MVC。异常处理。模特。usernamepasswordnmatchexception,Artech .MVC。异常处理'错误视图=' usernamepasswordnmatcheerror '/artech。异常处理如上面的配置所示,我们为无效用户名异常和usernamepasswordnatmatchexception这两种异常类型定义了不同的错误视图,分别是" InvalideUserNameError "和“UserNamePasswordNotMatchError”,详细定义如下所示:
@ { Layout=null}!DOCTYPE html html标题错误/标题/标题正文p style='有色;很抱歉,您指定的用户名不存在!/p/body/html @ { Layout=null;} !DOCTYPE html html标题错误/标题/标题正文p style='有色;抱歉,密码与给定的用户名不匹配!/p /body /html现在我们按照上面的方式运行我们的程序,在分别输入错误的用户名和密码的情况下会自动显现相应的错误页面。
四、自定义动作调用器:异常动作调用器
对于上述的两种不同的异常处理方式最终是通过自定义的ActionInvoker来实现的,我们将其命名为异常调用程序。如下面的代码片断所式,异常调用程序直接继承自ControllerActionInvoker。属性例外政策是一个基于指定的异常策略名称创建的ExceptionPolicyImpl对象,用于针对EntLib进行的异常处理。而属性GetErrorView是一个用于获得作为错误页面的查看结果对象的委托。整个异常处理的核心定义在InvokeAction方法中,该方法中指定的handleErrorActionName参数代表的是"异常处理操作名称",整个方法就是按照上述的异常处理策略实现的。
使用系统;使用系统。集合。通用;使用系统Linq .使用系统网络.使用系统网络。手动音量调节使用阿尔特奇.MVC。异常处理。配置;使用微软。实践。企业库。公共。配置;使用微软。实践。企业库。例外处理;命名空间阿尔特奇.Mvc。异常处理{公共类异常调用程序ControllerActionInvoker {受保护的异常处理设置异常处理设置{ get私有集;}受保护的虚拟Funcstring、HandleErrorInfo、ViewResult GetErrorView { get私有集;}公共异常策略{获取私有集;} public ExceptionActionInvoker(字符串异常策略、函数字符串、句柄错误信息、视图结果获取错误视图){这.异常策略=企业库容器电流。getinstancexceptionpolicy impl(异常策略);这个GetErrorView=getErrorView这个。异常处理设置=异常处理设置GetSection();}公共重写bool调用操作(控制器上下文控制器上下文,字符串handleerractionname){异常上下文异常上下文=作为异常上下文的控制器上下文;if(null==exceptionContext){ 0抛出新的ArgumentException(' controllerContext必须是“exceptionContext!”,' controllerContext ');}请尝试{异常上下文.异常处理=真如果(这个。异常策略。处理异常(异常上下文。异常)){ HandleRethrownException(异常上下文);} else { if(ExceptionHandlingContext).当前。错误。计数==0) {异常处理上下文。当前错误。添加(异常上下文。异常。消息);}控制器描述符控制器描述符=这个.GetControllerDescriptor(exceptionContext);操作描述符handleerraction=查找操作(异常上下文,controllerDescriptor,handler action name);if (null!=handleErrorAction){ IDictionaryString,对象参数=GetParameterValues(控制器上下文,handleErrorAction);异常上下文。结果=这个调用操作方法(异常上下文,handleErrorAction,参数);} else { HandleRethrownException(异常上下文);} }返回true} catch(异常ex){异常上下文.异常=exhandlethrowexception(异常上下文);返回真;} }受保护的虚拟void handlethrowexception(异常上下文异常上下文){ string error viewname=this .geterroviewname(异常上下文.异常。GetType());string controllerName=(字符串)异常上下文.RouteData。GetRequiredString('控制器');字符串操作=(字符串)异常上下文.RouteData。GetRequiredString('操作');句柄错误信息句柄错误信息=新的句柄错误信息(异常上下文.异常,controllerName,action);异常上下文。结果=这个. GetErrorView(errorViewName,HandleErrorInfo);}受保护的字符串GetErrorViewName(类型异常类型){异常错误视图元素元素=异常处理设置.异常错误报告CastExceptionErrorViewElement().FirstOrDefault(el=el .异常类型==异常类型);if(null!=元素){返回元素ErrorView} if(null==元素null!=异常类型BaseType!=null){ 0返回GetErrorViewName(异常类型. BaseType);} else {返回"错误";} } } }五、自定义控制器:基本控制器
优秀的推理者杨俊钦先生控制器(控制器)哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟基本控制器绿筠小姐。exceptionactioninvoker范文范文范文范文范文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文阿文,1821年一个例外(一次性异常)高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升高升。
使用系统;使用系统网络。mvcartech命名空间MVC。异常处理{公共抽象类基控制器{公共基控制器(字符串异常策略){ func ring,HandleErrorInfo,view result getrrow=(视图名,handleErrorInfo)=此处。视图(视图名称、句柄错误信息):这一点例外者=新的exception actor(exception collection,geterrorview)公共基础控制器(例外操作调用程序){ this。exceptionationker=操作调用程序;}公共虚拟例外论者例外论者{获取私人集;}受保护的虚拟字符串gethandleroractionname(字符串操作名){返回字符串。格式(“在{ 0 }错误时”,操作名称);}受保护的覆盖使一个异常无效(异常上下文filtercontext){使用(异常处理上下文cope=新的异常处理上下文cope(filtercontext)){字符串操作名称=路由数据.getrquiryedstring(' action ');字符串handleErrorActionName=this .gethandleroractionname(操作名);这一点例外者。invoke(筛选上下文,处理roractionname);foreach(异常处理上下文中的var误差).当前。错误){模型状态.addmodelarrror(Guid).NewGuid().ToString()错误错误消息(错误消息):} } } } }丶:哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟一个例外(一次性异常)-你好-你好例外管理上下文范围(卓越的可管理性上下文库)绿筠小姐。孟尝君,安藤仁例外管理上下文范围(卓越的可管理性上下文库)吾曰例外HandlingContext上下文哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟哟。exceptionhandlingcontext那是什么,阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖阿祖异常上下文(例外上下文)你好ModelErrorCollection,青梅竹马当前(当前)你好例外HandlingContext上下文绿筠。
公共类异常处理上下文{ [ThreadStatic]专用静态异常处理上下文当前;公共异常上下文异常上下文{获取私人集;}公共模型错误集合错误{ get私人集;}公共异常处理上下文{ this }公共异常上下文异常上下文=异常上下文:这一点errors=新模型错误集合();}公共静态异常处理上下文当前{ get { return current } set { current=value } }哦,天啊基本控制器什么事一个例外(一次性异常)高昌哥,四爷优秀的推理者什么事InvokeAction(调用方)哎哎哎,哥哥哥哥哥哥哥哥例外HandlingContext上下文什么事ModelError(模型错误)阿叔阿叔阿叔ModelState(模型状态)何曰。盖兹诺盖兹诺盖兹诺盖兹诺盖兹诺validationsummary(验证模型)1740年。-你好-你好,我的天啊,我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊错误消息settinghandler-错误讯息处理程式是吴亚玲,胡志明是胡志明例外HandlingContext上下文什么事错误你是谁。
[configuration element type(type of)(error messagesettingdata)]]公共类error messagesettinghandler iexceptionhandler { public string错误消息{ get私人集;} public error messagesettinghandler(字符串错误消息){此错误消息=错误消息;}公共异常处理异常{ if(null==异常处理上下文当前)}抛出新的无效操作异常(' ');} if(stringisnullorempty(此错误消息)){异常处理上下文当前错误sadd(异常消息);} else {异常处理上下文当前错误sadd(此错误消息);}返回异常;} }范仲淹?范仲淹:http://夏仔。JB 51。net/201701/马钰/异常处理_ JB 51。rar
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。