亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

ASP

ASP.NET MVC異常處理模塊簡(jiǎn)單教程-ASP.NET教程實(shí)例

時(shí)間:2024-08-15 02:26:32 ASP 我要投稿
  • 相關(guān)推薦

ASP.NET MVC異常處理模塊簡(jiǎn)單教程-ASP.NET教程實(shí)例推薦

  異常處理是每個(gè)系統(tǒng)必不可少的一個(gè)重要部分,它可以讓我們的程序在發(fā)生錯(cuò)誤時(shí)友好地提示、記錄錯(cuò)誤信息,更重要的是不破壞正常的數(shù)據(jù)和影響系統(tǒng)運(yùn)行。

  在MVC中處理異常,相信開始很多人都是繼承HandleErrorAttribute,然后重寫OnException方法,加入自己的邏輯,例如將異常信息寫入日志文件等。當(dāng)然,這并沒有任何不妥,但良好的設(shè)計(jì)應(yīng)該是場(chǎng)景驅(qū)動(dòng)的,是動(dòng)態(tài)和可配置的。

  簡(jiǎn)單地說,不同的場(chǎng)景有不同的需求,而我們的程序需要更好的面對(duì)變化。當(dāng)然,繼承HandleErrorAttribute也完全可以實(shí)現(xiàn)上面所說的,只不過這里我不打算去擴(kuò)展它,而是重新編寫一個(gè)模塊,并且可以與原有的HandleErrorAttribute共同使用。

  下面讓我們一起來學(xué)習(xí)ASP.NET MVC異常處理模塊編程實(shí)例吧!

  2.1 定義配置信息

  從上面已經(jīng)可以知道我們要做的事了,針對(duì)不同的異常,我們希望可以配置它的處理程序,錯(cuò)誤頁等。如下一個(gè)配置:

  <!--自定義異常配置-->

  <settingException>

  <exceptions>

  <!--add優(yōu)先級(jí)高于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 節(jié)點(diǎn)用于增加具體的異常,它的 exception 屬性是必須的,而view表示錯(cuò)誤頁,handler表示具體處理程序,如果view和handler都沒有,異常將交給默認(rèn)的HandleErrorAttribute處理。而group節(jié)點(diǎn)用于分組,例如上面的UserNameEmptyException和EmailEmptyException對(duì)應(yīng)同一個(gè)處理程序和視圖。

  程序會(huì)反射讀取這個(gè)配置信息,并創(chuàng)建相應(yīng)的對(duì)象。我們把這個(gè)配置文件放到Web.config中,保證它可以隨時(shí)改隨時(shí)生效。

  2.2 異常信息包裝對(duì)象

  這里我們定義一個(gè)實(shí)體對(duì)象,對(duì)應(yīng)上面的節(jié)點(diǎn)。如下:

  public class ExceptionConfig

  {

  /// <summary>

  /// 視圖

  /// </summary>

  public string View{get;set;}

  /// <summary>

  /// 異常對(duì)象

  /// </summary>

  public Exception Exception{get;set;}

  /// <summary>

  /// 異常處理程序

  /// </summary>

  public IExceptionHandler Handler{get;set;}

  }

  2.3 定義Handler接口

  上面我們說到,不同異?赡苄枰煌幚矸绞。這里我們?cè)O(shè)計(jì)一個(gè)接口如下:

  public interface IExceptionHandler

  {

  /// <summary>

  /// 異常是否處理完成

  /// </summary>

  bool HasHandled{get;set;}

  /// <summary>

  /// 處理異常

  /// </summary>

  /// <param name="ex"></param>

  void Handle(Exception ex);

  }

  各種異常處理程序只要實(shí)現(xiàn)該接口即可。

  2.3 實(shí)現(xiàn)IExceptionFilter

  這是必須的。如下,實(shí)現(xiàn)IExceptionFilter接口,SettingExceptionProvider會(huì)根據(jù)異常對(duì)象類型從配置信息(緩存)獲取包裝對(duì)象。

  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)

  {

  //執(zhí)行Handle方法

  config.Handler.Handle(filterContext.Exception);

  if (config.Handler.HasHandled)

  {

  //異常已處理,不需要后續(xù)操作

  filterContext.ExceptionHandled = true;

  return;

  }

  }

  //否則,如果有定制頁面,則顯示

  if(!string.IsNullOrEmpty(config.View))

  {

  //這里還可以擴(kuò)展成實(shí)現(xiàn)IView的視圖

  ViewResult view = new ViewResult();

  view.ViewName = config.View;

  filterContext.Result = view;

  filterContext.ExceptionHandled = true;

  return;

  }

  //否則將異常繼續(xù)傳遞

  }

  }

  2.4 讀取配置文件,創(chuàng)建異常信息包裝對(duì)象

  這部分代碼比較多,事實(shí)上,你只要知道它是在讀取web.config的自定義配置節(jié)點(diǎn)即可。SettingExceptionProvider用于提供容器對(duì)象。

  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;

  }

  }

  //根據(jù)完全限定名創(chuàng)建IExceptionHandler對(duì)象

  private static IExceptionHandler CreateHandler(string fullName)

  {

  if(string.IsNullOrEmpty(fullName))

  {

  return null;

  }

  Type type = Type.GetType(fullName);

  return Activator.CreateInstance(type) as IExceptionHandler;

  }

  //根據(jù)完全限定名創(chuàng)建Exception對(duì)象

  private static Exception CreateException(string fullName)

  {

  if(string.IsNullOrEmpty(fullName))

  {

  return null;

  }

  Type type = Type.GetType(fullName);

  return Activator.CreateInstance(type) as Exception;

  }

  }

  以下是各個(gè)配置節(jié)點(diǎn)的信息:

  settingExceptions節(jié)點(diǎn):

  /// <summary>

  /// settingExceptions節(jié)點(diǎn)

  /// </summary>

  public class SettingExceptionSection : ConfigurationSection

  {

  [ConfigurationProperty("exceptions",IsRequired=true)]

  public ExceptionsElement Exceptions

  {

  get

  {

  return (ExceptionsElement)base["exceptions"];

  }

  }

  }

  exceptions節(jié)點(diǎn):

  /// <summary>

  /// exceptions節(jié)點(diǎn)

  /// </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節(jié)點(diǎn)集:

  /// <summary>

  /// group節(jié)點(diǎn)集

  /// </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節(jié)點(diǎn):

  /// <summary>

  /// group節(jié)點(diǎn)

  /// </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節(jié)點(diǎn)集:

  /// <summary>

  /// add節(jié)點(diǎn)集

  /// </summary>

  public class AddCollection : ConfigurationElementCollection

  {

  /*override*/

  protected override ConfigurationElement CreateNewElement()

  {

  return new AddElement();

  }

  protected override object GetElementKey(ConfigurationElement element)

  {

  return element;

  }

  }

  add節(jié)點(diǎn):

  /// <summary>

  /// add節(jié)點(diǎn)

  /// </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;

  }

  }

  }

  測(cè)試

  ok,下面測(cè)試一下,首先要在FilterConfig的RegisterGlobalFilters方法中在,HandlerErrorAttribute前注冊(cè)我們的過濾器:

  filters.Add(new SettingHandleErrorFilter())。

  3.1 準(zhǔn)備異常對(duì)象

  準(zhǔn)備幾個(gè)簡(jiǎn)單的異常對(duì)象:

  public class PasswordErrorException : Exception{}

  public class UserNameEmptyException : Exception{}

  public class EmailEmptyException : Exception{}

  3.2 準(zhǔn)備Handler

  針對(duì)上面的異常,我們準(zhǔn)備兩個(gè)Handler,一個(gè)處理密碼錯(cuò)誤異常,一個(gè)處理空異常。這里沒有實(shí)際處理代碼,具體怎么處理,應(yīng)該結(jié)合具體業(yè)務(wù)了。如:

  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 拋出異常

  按照上面的配置,我們?cè)贏ction中手動(dòng)throw異常

  public ActionResult Index()

  {

  throw new PasswordErrorException();

  }

  public ActionResult Index2()

  {

  throw new UserNameEmptyException();

  }

  public ActionResult Index3()

  {

  throw new EmailEmptyException();

  }

  可以看到,相應(yīng)的Handler會(huì)被執(zhí)行,瀏覽器也會(huì)出現(xiàn)我們配置的錯(cuò)誤頁面。

【ASP.NET MVC異常處理模塊簡(jiǎn)單教程-ASP.NET教程實(shí)例】相關(guān)文章:

解讀ASP.NET 5 MVC6系列教程06-27

ASP.NET 主題配置教程08-21

使用ASP.NET創(chuàng)建線程教程07-14

ASP.NET架構(gòu)及開發(fā)技術(shù)詳解教程08-17

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程08-30

Asp.Net數(shù)據(jù)輸出到EXCEL表格中的教程05-23

Javascript實(shí)例教程08-22

photoshop實(shí)例教程07-08

CentOS上搭建Nginx+Mono運(yùn)行asp.net環(huán)境配置教程07-25

ps發(fā)芽實(shí)例教程06-25