温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

ASP.NET MVC中有哪些异常处理模块

发布时间:2021-07-16 15:00:49 来源:亿速云 阅读:234 作者:Leah 栏目:开发技术

本篇文章为大家展示了ASP.NET MVC中有哪些异常处理模块,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

定义配置信息

  从上面已经可以知道我们要做的事了,针对不同的异常,我们希望可以配置它的处理程序,错误页等。如下一个配置:

<!--自定义异常配置--> <settingException>  <exceptions>   <!--add优先级高于group-->   <add exception="Exceptions.PasswordErrorException"      view ="PasswordErrorView"      handler="ExceptionHandlers.PasswordErrorExceptionHandler"/>   <groups>    <!--group可以配置一种异常的view和handler-->    <group view="EmptyErrorView" handler="ExceptionHandlers.EmptyExceptionHandler">     <add exception="Exceptions.UserNameEmptyException"/>     <add exception="Exceptions.EmailEmptyException"/>    </group>       </groups>  </exceptions> </settingException>

  其中,add 节点用于增加具体的异常,它的 exception 属性是必须的,而view表示错误页,handler表示具体处理程序,如果view和handler都没有,异常将交给默认的HandleErrorAttribute处理。而group节点用于分组,例如上面的UserNameEmptyException和EmailEmptyException对应同一个处理程序和视图。

  程序会反射读取这个配置信息,并创建相应的对象。我们把这个配置文件放到Web.config中,保证它可以随时改随时生效。

2.2 异常信息包装对象

  这里我们定义一个实体对象,对应上面的节点。如下:

public class ExceptionConfig {   /// <summary>   /// 视图   /// </summary>   public string View{get;set;}     /// <summary>   /// 异常对象   /// </summary>   public Exception Exception{get;set;}     /// <summary>   /// 异常处理程序   /// </summary>   public IExceptionHandler Handler{get;set;} }

2.3 定义Handler接口

  上面我们说到,不同异常可能需要不同处理方式。这里我们设计一个接口如下:

public interface IExceptionHandler {   /// <summary>   /// 异常是否处理完成   /// </summary>   bool HasHandled{get;set;}     /// <summary>   /// 处理异常   /// </summary>   /// <param name="ex"></param>   void Handle(Exception ex); }

  各种异常处理程序只要实现该接口即可。

2.3 实现IExceptionFilter

  这是必须的。如下,实现IExceptionFilter接口,SettingExceptionProvider会根据异常对象类型从配置信息(缓存)获取包装对象。

public class SettingHandleErrorFilter : IExceptionFilter {   public void OnException(ExceptionContext filterContext)   {     if(filterContext == null)     {       throw new ArgumentNullException("filterContext");     }     ExceptionConfig config = SettingExceptionProvider.Container[filterContext.Exception.GetType()];     if(config == null)     {       return;     }     if(config.Handler != null)     {       //执行Handle方法               config.Handler.Handle(filterContext.Exception);       if (config.Handler.HasHandled)       {         //异常已处理,不需要后续操作         filterContext.ExceptionHandled = true;         return;       }     }           //否则,如果有定制页面,则显示     if(!string.IsNullOrEmpty(config.View))     {       //这里还可以扩展成实现IView的视图       ViewResult view = new ViewResult();       view.ViewName = config.View;       filterContext.Result = view;       filterContext.ExceptionHandled = true;       return;     }     //否则将异常继续传递   } }

2.4 读取配置文件,创建异常信息包装对象

  这部分代码比较多,事实上,你只要知道它是在读取web.config的自定义配置节点即可。SettingExceptionProvider用于提供容器对象。

public class SettingExceptionProvider {   public static Dictionary<Type, ExceptionConfig> Container =     new Dictionary<Type, ExceptionConfig>();     static SettingExceptionProvider()   {     InitContainer();   }     //读取配置信息,初始化容器   private static void InitContainer()   {     var section = WebConfigurationManager.GetSection("settingException") as SettingExceptionSection;     if(section == null)     {       return;     }     InitFromGroups(section.Exceptions.Groups);     InitFromAddCollection(section.Exceptions.AddCollection);   }     private static void InitFromGroups(GroupCollection groups)   {                foreach (var group in groups.Cast<GroupElement>())     {        ExceptionConfig config = new ExceptionConfig();       config.View = group.View;       config.Handler = CreateHandler(group.Handler);       foreach(var item in group.AddCollection.Cast<AddElement>())       {         Exception ex = CreateException(item.Exception);         config.Exception = ex;         Container[ex.GetType()] = config;       }     }   }     private static void InitFromAddCollection(AddCollection collection)   {     foreach(var item in collection.Cast<AddElement>())     {       ExceptionConfig config = new ExceptionConfig();       config.View = item.View;       config.Handler = CreateHandler(item.Handler);       config.Exception = CreateException(item.Exception);       Container[config.Exception.GetType()] = config;     }   }     //根据完全限定名创建IExceptionHandler对象   private static IExceptionHandler CreateHandler(string fullName)         {     if(string.IsNullOrEmpty(fullName))     {       return null;     }     Type type = Type.GetType(fullName);     return Activator.CreateInstance(type) as IExceptionHandler;   }     //根据完全限定名创建Exception对象   private static Exception CreateException(string fullName)   {     if(string.IsNullOrEmpty(fullName))     {       return null;     }     Type type = Type.GetType(fullName);     return Activator.CreateInstance(type) as Exception;   } }

  以下是各个配置节点的信息:

  settingExceptions节点:

/// <summary> /// settingExceptions节点 /// </summary> public class SettingExceptionSection : ConfigurationSection {   [ConfigurationProperty("exceptions",IsRequired=true)]   public ExceptionsElement Exceptions   {     get     {       return (ExceptionsElement)base["exceptions"];     }   } }

  exceptions节点:

/// <summary> /// exceptions节点 /// </summary> public class ExceptionsElement : ConfigurationElement {   private static readonly ConfigurationProperty _addProperty =     new ConfigurationProperty("", typeof(AddCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);     [ConfigurationProperty("", IsDefaultCollection = true)]   public AddCollection AddCollection   {     get     {       return (AddCollection)base[_addProperty];     }   }     [ConfigurationProperty("groups")]   public GroupCollection Groups   {     get     {       return (GroupCollection)base["groups"];     }   } }

  Group节点集:

/// <summary> /// group节点集 /// </summary> [ConfigurationCollection(typeof(GroupElement),AddItemName="group")] public class GroupCollection : ConfigurationElementCollection {      /*override*/     protected override ConfigurationElement CreateNewElement()   {     return new GroupElement();   }     protected override object GetElementKey(ConfigurationElement element)   {     return element;   } }

  group节点:

/// <summary> /// group节点 /// </summary> public class GroupElement : ConfigurationElement {   private static readonly ConfigurationProperty _addProperty =     new ConfigurationProperty("", typeof(AddCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);     [ConfigurationProperty("view")]   public string View   {     get     {       return base["view"].ToString();     }   }     [ConfigurationProperty("handler")]   public string Handler   {     get     {       return base["handler"].ToString();     }   }     [ConfigurationProperty("", IsDefaultCollection = true)]   public AddCollection AddCollection   {     get     {       return (AddCollection)base[_addProperty];     }   }     }

  add节点集:

/// <summary> /// add节点集 /// </summary>   public class AddCollection : ConfigurationElementCollection {        /*override*/     protected override ConfigurationElement CreateNewElement()   {     return new AddElement();   }     protected override object GetElementKey(ConfigurationElement element)   {     return element;   } }

  add节点:

/// <summary> /// add节点 /// </summary> public class AddElement : ConfigurationElement {   [ConfigurationProperty("view")]   public string View   {     get     {       return base["view"] as string;     }   }     [ConfigurationProperty("handler")]   public string Handler   {     get     {       return base["handler"] as string;     }   }     [ConfigurationProperty("exception", IsRequired = true)]   public string Exception   {     get     {       return base["exception"] as string;     }   } }

三、测试

  ok,下面测试一下,首先要在FilterConfig的RegisterGlobalFilters方法中在,HandlerErrorAttribute前注册我们的过滤器:

  filters.Add(new SettingHandleErrorFilter())。

3.1 准备异常对象

   准备几个简单的异常对象:

public class PasswordErrorException : Exception{} public class UserNameEmptyException : Exception{} public class EmailEmptyException : Exception{}

3.2 准备Handler

  针对上面的异常,我们准备两个Handler,一个处理密码错误异常,一个处理空异常。这里没有实际处理代码,具体怎么处理,应该结合具体业务了。如:

public class PasswordErrorExceptionHandler : IExceptionHandler {   public bool HasHandled{get;set;}       public void Handle(Exception ex)   {     //具体处理逻辑...   } }   public class EmptyExceptionHandler : IExceptionHandler {   public bool HasHandled { get; set; }     public void Handle(Exception ex)   {     //具体处理逻辑...   } }

3.3 抛出异常

  按照上面的配置,我们在Action中手动throw异常

public ActionResult Index() {   throw new PasswordErrorException(); } public ActionResult Index2() {   throw new UserNameEmptyException(); } public ActionResult Index3() {   throw new EmailEmptyException(); }

上述内容就是ASP.NET MVC中有哪些异常处理模块,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI