zoukankan      html  css  js  c++  java
  • asp.net mvc3异常处理和身份验证 转

    现在项目是这样处理的,如果兄弟们更好的方法,分享给我哦

    异常处理:

    这里我写的是全局捕获异常,捕获一些我们漏掉的异常

    一般我们都会自定义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

  • 相关阅读:
    IDEA与Eclipse
    解释器模式
    设计模式(十一)—— 策略模式
    设计模式(六)—— 装饰模式
    Java注解
    Spring源码阅读(二)—— AOP
    业务开发(八)—— Maven
    高性能MySQL笔记
    Java源码阅读(六)—— ReentrantLock
    业务开发(六)—— MyBatis框架
  • 原文地址:https://www.cnblogs.com/EasyLive2006/p/2741946.html
Copyright © 2011-2022 走看看