如何在ASP.NET MVC中使用动作过滤器来路由到不同的视图但使用相同的URL?

时间:2011-09-29 18:20:58

标签: asp.net-mvc asp.net-mvc-3

是否有可能制作一个过滤器,在(大部分)处理完控制器操作后,检查某个测试条件并透明地路由到用户的不同视图(即URL没有变化)? / p>

这是我对某些伪代码的最佳猜测:

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        // If some condition is true
        //  Change the resulting view resolution to XYZ

        base.OnResultExecuting(filterContext);
    }

4 个答案:

答案 0 :(得分:7)

filterContext.Result = new ViewResult
{
    ViewName = "~/Views/SomeController/SomeView.cshtml"
};

这会使行动的执行短路。

答案 1 :(得分:1)

您也可以从动作中返回视图

  public ActionResult Index()
                {
                    return View(@"~/Views/SomeView.aspx");
                }

答案 2 :(得分:0)

我已将ASP.NET MVC操作过滤器的AuthorizeAttribute扩展为DCIMAuthorize,其中我执行了一些安全检查,如果用户未经过身份验证或授权,则操作过滤器将使用户访问被拒绝的页面。我的实现如下:

public class DCIMAuthorize : AuthorizeAttribute
{

    public string BusinessComponent { get; set; }

    public string Action { get; set; }
    public bool ResturnJsonResponse { get; set; }
    public bool Authorize { get; set; }

    public DCIMAuthorize()
    {
        ResturnJsonResponse = true;
    }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {

        try
        {
            //to check whether user is authenticated
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;
            //to check site level access
            if (HttpContext.Current.Session["UserSites"] != null)
            {
                var allSites = (VList<VSiteList>)HttpContext.Current.Session["UserSites"];
                if (allSites.Count <= 0)
                    return false;
            }
            else
                return false;

            // use Authorize for authorization
            Authorize = false;

            string[] roles = null;
            //get roles for currently login user
            if (HttpContext.Current.Session["Roles"] != null)
            {
                roles = (string[])HttpContext.Current.Session["Roles"];
            }

            if (roles != null)
            {
                //for multiple roles
                string[] keys = new string[roles.Length];
                int index = 0;
                // for each role, there is separate key
                foreach (string role in roles)
                {
                    keys[index] = role + "-" + BusinessComponent + "-" + Action;
                    index++;
                }

                //access Authorization Details and compare with keys  
                if (HttpContext.Current.Application["AuthorizationDetails"] != null)
                {
                    Hashtable authorizationDetails = (Hashtable)HttpContext.Current.Application["AuthorizationDetails"];

                    bool hasKey = false;
                    foreach (var item in keys)
                    {
                        hasKey = authorizationDetails.ContainsKey(item);
                        if (hasKey)
                        {
                            Authorize = hasKey;
                            break;
                        }
                    }

                }
            }
            return base.AuthorizeCore(httpContext);
        }
        catch (Exception)
        {

            throw;
        }
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        try
        {
            filterContext.Controller.ViewData["ResturnJsonResponse"] = ResturnJsonResponse;
            base.OnAuthorization(filterContext);
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                // auth failed, redirect to login page
                filterContext.Result = new HttpUnauthorizedResult();

                return;
            }

            if (!Authorize)
            {
                //Authorization failed, redirect to Access Denied Page
                filterContext.Result = new RedirectToRouteResult(
                   new RouteValueDictionary{{ "controller", "Base" },
                                             { "action", "AccessDenied" }
                                             //{ "returnUrl",    filterContext.HttpContext.Request.RawUrl }
                                            });
            }
        }
        catch (Exception)
        {

            throw;
        }
    }
}

答案 3 :(得分:0)

这就是我最终做的事情,并且包含在一个可重用的属性中,最棒的是它在根据您的要求重定向(或应用您想要的任何结果)时保留原始URL:

public class AuthoriseSiteAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        // Perform your condition, or straight result assignment here.
        // For me I had to test the existance of a cookie.
        if (yourConditionHere)
            filterContext.Result = new SiteAccessDeniedResult();
    }

}

public class SiteAccessDeniedResult : ViewResult
{
    public SiteAccessDeniedResult()
    {
        ViewName = "~/Views/SiteAccess/Login.cshtml";
    }
}

然后只需将属性[SiteAccessAuthorise]添加到您希望应用授权访问权限的控制器(在我的情况下)或将其添加到BaseController。确保您重定向到底层控制器的操作虽然没有属性,但您将陷入无限循环!