asp.net mvc3异常处理和身份验证
本文导语: 本文介绍 asp.net mvc3异常处理和身份验证 的相关内容,正在学习asp.net mvc3的兄弟们,可以参考下。现在项目是这样处理的,如果兄弟们更好的方法,分享给我哦。 异常处理: 这里我写的是全局捕获异常,捕获一...
本文介绍 asp.net mvc3异常处理和身份验证 的相关内容,正在学习asp.net mvc3的兄弟们,可以参考下。现在项目是这样处理的,如果兄弟们更好的方法,分享给我哦。
异常处理:
这里我写的是全局捕获异常,捕获一些我们漏掉的异常。一般我们都会自定义500和400。
在web.config中这样写
这里的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中,可以看到默认的异常处理机制
{
filters.Add(new HandleErrorAttribute());
}
在mvc项目新建一文件夹Common放我们公用的类,新建一类AppHandleErrorAttribute继承HandleErrorAttribute,重写OnException方法
{
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的定义
///
/// 此异常是后端和前端交互使用,后端可以抛出异常,包含异常的信息,前端捕获WebException,并将错误信息显示给用户
/// 未捕获的异常可以在Global中处理(记日志)
///
[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方法的定义
/// 500
///
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特性
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 allowGuestPages = new Dictionary();
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方法再添加一筛选器,如下
{
filters.Add(new AppHandleErrorAttribute());
filters.Add(new AppAuthorizeAttribute());
}
好了,大功告成,不用在每个controller加Authorize了。
原文链接:http://www.cnblogs.com/baobeiyu/archive/2012/10/26/2740931.html