现在项目是这样处理的,如果兄弟们更好的方法,分享给我哦
异常处理:
这里我写的是全局捕获异常,捕获一些我们漏掉的异常
一般我们都会自定义500和400
在web.config中这样写
<customErrors mode=
"RemoteOnly"
defaultRedirect=
"500"
>
<error statusCode=
"500"
redirect=
"500"
/>
<error statusCode=
"404"
redirect=
"404"
/>
</customErrors>
|
这里的500和400是路由过去的,在Global中添加
// 500 错误 routes.MapRoute("500", "500", new { controller = "SiteStatus", action = "_500" }); // 404 routes.MapRoute("404", "404", new { controller = "SiteStatus", action = "_404" });
对应的,有一个 SiteStatusController,其中包含_500 action和_404 action
在Global中,可以看到默认的异常处理机制
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); }
在mvc项目新建一文件夹Common放我们公用的类,新建一类AppHandleErrorAttribute继承HandleErrorAttribute,重写OnException方法
public class AppHandleErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { // 记日志 ILogger log = LogManager.GetCurrentClassLogger(); Exception ex = filterContext.Exception; if (ex is WebException) { log.Error("自定义异常(WebException):", ex);
// 表示异常已处理,直接跳到500显示错误消息 filterContext.ExceptionHandled = true; filterContext.Result = new RedirectToRouteResult("500", new RouteValueDictionary(new { message = ex.Message })); } else { log.Error("系统异常:", ex); } } }
WebAppexception的定义
/// <summary> /// 此异常是后端和前端交互使用,后端可以抛出异常,包含异常的信息,前端捕获WebException,并将错误信息显示给用户 /// 未捕获的异常可以在Global中处理(记日志) /// </summary> [Serializable] public class WebException : ApplicationException { public WebException() { } public WebException(string message) : base(message) { } public WebException(string message, Exception innerException) : base(message, innerException) { } protected WebException(SerializationInfo info, StreamingContext context) : base(info, context) { } }
现在我们把 filters.Add(newHandleErrorAttribute());
换成 filters.Add(new AppHandleErrorAttribute());
AppHandleErrorAttribute 处理之后还是会跳转到500页面,500方法的定义
/// <summary> /// 500 /// </summary> public ActionResult _500(string message = "处理您的请求时出错,请联系管理员或稍后重试。") { // 如果是ajax请求我们返回-1024,前台有捕获 if (Request.IsAjaxRequest()) { return Json(new { Code = -1024 }, JsonRequestBehavior.AllowGet); } else { ViewBag.Message = message; return View(); } }
如果是ajax请求我们return View()不行,那么我们返回一个json给前端的ajax请求
前端的ajax请求也要处理一下
// 重写jQuery.ajax使能处理服务端异常,以及处理ModelBase var ajax = jQuery.ajax; jQuery.ajax = function (settings) { // 自定义异常消息 var exceptionMsg = settings["exceptionMsg"] || "处理您的请求时出错,请联系管理员或稍后重试。"; // 异常跳转方式 1:弹框, 2:跳转到错误页面 var redirectType = settings["type"] || 1; // 开启自动处理Model,默认关闭 var enableModelHandle = settings["enableModelError"] || false; var successCallback = settings["success"]; // 在success中处理,jquery.ajax的error函数好像不能写,频繁报错 settings["success"] = function (model) { // 这里处理异常(在服务器,ajax 未捕获的异常,会返回 -1024) if (model.Code === -1024) { if (redirectType === 1) { alert(exceptionMsg); } else { location.href = "/500"; } } // 不是异常,处理ModelBase else { // 开启了自动处理Model if (enableModelHandle) { // 现在是直接弹框显示后端定义的Message alert(model.Message); } // 如果定义了success函数,则调用它,并传入model libra.isFunction(successCallback) && successCallback.call(null, model); } } // 调用jquery.ajax函数,把我们已经写好的settings传过去。 ajax(settings); }
好了,这样前后台结合一下就基本可以了。
身份验证:
新建一个默认的mvc项目的时候可以看到模版中有的action添加了Authorize特性
[Authorize] public ActionResult ChangePassword() { return View(); }
这个也可以添加在controller上,嫌麻烦的话,可以新建一个BaseController,然后所有的Controller继承它就可以了。
这里我们还是在Common中添加一类AppAuthorizeAttribute,继承AuthorizeAttribute,重写它的OnAuthorization方法
public class AppAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { // 过滤不需要验证的页面 allowGuestPages.Add("controllerName", "|actionName1|actionName2|"); // 过滤整个控制器用 allowGuestPages.Add("controllerName", "all"); Dictionary<string, string> allowGuestPages = new Dictionary<string, string>(); allowGuestPages.Add("home", "all"); allowGuestPages.Add("onlineuser", "all"); string currentControllerName = MvcUtil.GetControllerName(filterContext.RouteData).ToLower(); string currentActionName = MvcUtil.GetActionName(filterContext.RouteData).ToLower(); string allowActions = string.Empty; if (allowGuestPages.TryGetValue(currentControllerName, out allowActions)) { allowActions = allowActions.ToLower(); if (allowActions == "all" || allowActions.Contains("|" + currentActionName + "|")) { return; } } // 没有登录,跳到登录页面 if (!OnlineUser.Instantce.IsLogin()) { filterContext.Result = new RedirectToRouteResult("login", routeValues); } } }
在Global文件中RegisterGlobalFilters方法再添加一筛选器,如下
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new AppHandleErrorAttribute()); filters.Add(new AppAuthorizeAttribute()); }
好了,大功告成,不用在每个controller加Authorize了。。
原文:http://www.cnblogs.com/baobeiyu/archive/2012/10/26/2740931.html