Asp.NET MVC动作过滤器自定义异常处理

时间:2013-11-26 19:34:45

标签: c# asp.net-mvc exception-handling actionfilterattribute

上下文:

我们有一个与IBM的P8内容引擎交互的Asp.NET MVC客户端。最终用户通过AD通过网络进行身份验证。但是,有时传递给我们的用户身份并不总是与我们所拥有的相匹配,因此我们无法检索用户的信息,我们的MVC应用程序也无法与AD交互。我有一个动作过滤器来执行此用户信息查找,有时查找结果为空。我想返回我的错误视图并将其传递给HandleErrorInfo模型。我尝试抛出一个异常,但不知怎的,HandleError甚至Application_Error块似乎都没有做任何事情。

这是我注册的自定义UserLookupAttribute过滤器:

public class UserLookupAttribute : ActionFilterAttribute, IActionFilter
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContextBase context = filterContext.HttpContext;
            UserInfo userInfo = null;
            if (context.User.Identity.IsAuthenticated)
            {
                if (context.Session != null && context.Session["UserInfo"] != null) { userInfo = (UserInfo)context.Session["UserInfo"]; }
                string networkId = (string.IsNullOrEmpty(SecurityConstants.UserImpersonateId)) ? GetNetworkId(context.User.Identity.Name) : GetNetworkId(SecurityConstants.UserImpersonateId);
                if (userInfo == null && !string.IsNullOrEmpty(networkId))
                {
                    userInfo = GetUserInfoCache(networkId);
                    if (userInfo != null)
                        context.Session["UserInfo"] = userInfo;
                }

                if (userInfo != null)
                {
                    context.Items["UserInfo"] = userInfo;
                    filterContext.Controller.ViewBag.User = userInfo;                    
                }
                //else
                //    throw new HttpException((int)HttpStatusCode.Unauthorized, "You login credential is not recognized by FileNet.");
            }
            base.OnActionExecuting(filterContext);
        }
}

Application_Error代码:

protected void Application_Error()
        {
            var httpContext = HttpContext.Current;

            var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
            var currentController = " ";
            var currentAction = " ";

            if (currentRouteData != null)
            {
                if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
                {
                    currentController = currentRouteData.Values["controller"].ToString();
                }

                if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
                {
                    currentAction = currentRouteData.Values["action"].ToString();
                }
            }

            var ex = Server.GetLastError();

            var controller = new ErrorController();
            var routeData = new RouteData();
            var action = "Index";

            if (ex is HttpException)
            {
                var httpEx = ex as HttpException;

                switch (httpEx.GetHttpCode())
                {
                    case 404:
                        action = "NotFound";
                        break;

                    // others if any

                    default:
                        action = "Index";
                        break;
                }
            }

            httpContext.ClearError();
            httpContext.Response.Clear();
            httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
            httpContext.Response.TrySkipIisCustomErrors = true;
            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = action;

            controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
            ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
        }

0 个答案:

没有答案
相关问题