一种mvc下处理异常的与http错误的方法
很多网站如果由于用户输入错了地址,出现了如下图的网页
又或者网站的bug导致的应用程序异常,搞出来个满屏的红黄黑,
出现类似情况一定让用户大跌眼镜,个人认为,http错误与应用程序异常的处理方式应该是我们所需关注的问题。
解决方案
1.定义1个枚举类型用来存储http错误码,与应用程序异常错误
public enum DictSystemErrorType { /// <summary> /// 系统错误 /// </summary> SystemError = 1, /// <summary> /// 系统异常 /// </summary> SystemException = 2, /// <summary> /// 404错误 /// </summary> Http404Error = 404, /// <summary> /// 500错误 /// </summary> Http500Error = 500 }
2.定义SystemErrorCollection静态类用来管理错误提示信息
public static class SystemErrorCollection { private static readonly IDictionary<int, string> SystemMsg = new Dictionary<int, string> { {1,"系统错误,请联系管理员!"}, {2,"系统出现异常,请联系管理员!"}, {404,"404错误,Really very sorry,The page not found!"}, {500,"500错误,Internal Server Error!"}, }; /// <summary> /// 获取错误提示 /// </summary> /// <param name="errCode"></param> /// <returns></returns> public static string GetSystemErrorMsg(int errCode) { return SystemMsg.SingleOrDefault(p => p.Key == errCode).Value; } }
3.mvc下Global.asax文件和webForm下的一样,都继承自System.Web.HttpApplication,
他们都包含Application_Error事件(当应用程序中遇到一个未处理的异常时,该事件被触发。)
定义Application_Error事件处理错误与异常
protected void Application_Error(object sender, EventArgs e) { Exception exception = Server.GetLastError(); Response.Clear(); var httpException = exception as HttpException; int errorCode = httpException == null ? (int)DictSystemErrorType.SystemException : httpException.GetHttpCode(); //记录log ... //发送错误邮件给网站管理人员 ... var routeData = new RouteData(); routeData.Values.Add("controller", "Error"); routeData.Values.Add("action", "error"); routeData.Values.Add("errorCode", errorCode); Server.ClearError(); IController errorController = new ErrorController(); errorController.Execute(new RequestContext(new HttpContextWrapper(this.Context), routeData)); }
4.添加ErrorController与Error Action
public class ErrorController : Controller { // // GET: /Error/ public ActionResult error() { int errorCode = (int)(this.RouteData.Values["errorCode"] ?? DictSystemErrorType.SystemError); ViewData["errorMsg"] = SystemErrorCollection.GetSystemErrorMsg(errorCode); return View(); } }
杂谈
为方便管理错误码与提示信息,定义了枚举类型与一个IDictionary字典。
然而同时维护这两个东西着实有些不变,还好可以通过反射取得枚举的提示信息。
不过最好把错误提示信息对应错误码持久化到数据库或者xml文件中,然后将其缓存起来。
如此可随时更新错误信息,无需修改程序。
IController是很简单的,它主要的用途在于提供了关于路由的工具来找到控制器并调用执行(Execute)
Controller的HandleUnknownAction:控制器找不到相关的Action将会呼叫 HandleUnknownAction
另外值得注意的是:
mvc下如果你的某个Controller或者自定义基类的controller重写了HandleUnknownAction方法,
那么出现http404错误的话,该Controller执行完HandleUnknownAction,将不会再执行Application_Error!