自定义属性重定向导致“不允许子操作执行重定向操作”错误

时间:2011-05-06 00:48:56

标签: asp.net-mvc

我的MVC 3 webapp有不同的部分需要检查用户是用户还是管理员,他们都可以访问相同的页面,除了一些页面有只有管理员可以看到的控制器(按钮和文本框)。我通过将用户的访问级别放入我的viewmodel并进行检查来进行检查:

@if (Model.UserAccess != "Viewer")
{
    [do something]
}

我在行动中检查登录用户的访问权限。如果会话超时,我会将它们重定向到登录页面。

我的动作从项目页面视图调用并作为部分加载:

@{Html.RenderAction("CategoryList", "Home", new { categoryId = Model.CategoryId });}

我的控制器:

public PartialViewResult CategoryList(int categoryid = 0)
{
    var useraccess = GetUseraccess();

    [blablabla stuff done here]

    var model = new CategoryViewModel()
    {
        CategoryList = categorylist
        UserAccess = useraccess
    };

    return PartialView(model);
}

public string GetUseraccess()
{
    var useraccess = "viewer"; //default

    var check = SessionCheck();
    if (check == "expired")
    {
        ModelState.AddModelError("", "Session expired. Please login again.");

        Response.Redirect("/Account/LogOn");
    }
    else if (check == "admin")
    {
        useraccess = "admin";
    }

    return useraccess;
}

public string SessionCheck()
{
    if (Session["UserAccess"] == null)
    {
        return "expired";
    }
    else if ((string)Session["UserAccess"] == "admin")
    {
        return "admin";
    }
    else // viewer
    {
        return "viewer";
    }
}

现在工作正常。但是我一直在尝试实现一个自定义属性,在触发控制器之前检查会话的到期时间:

public class CheckUserAccessSessionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var useraccess = filterContext.HttpContext.Session["UserAccess"];
        if ((string)useraccess == null)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Account", action = "LogOn" }));
        }
    }
}

[CheckUserAccessSession]
public PartialViewResult CategoryList(int categoryid = 0)
{
    [same stuff as above here]
}

我收到错误

Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.

我理解错误发生的原因。但我还没有找到如何绕过它。同样地,我想向我的操作发送一些来自另一个自定义属性的数据,但由于RedirectToRouteResult而无法正常工作。

2 个答案:

答案 0 :(得分:2)

您的问题是,您正在返回该操作方法的PartialViewResult,根据定义,该操作方法的输出将只是IIS提供的完整请求的一部分。您应该对提供部分视图所在的完整视图的操作方法进行权限检查。

从技术上讲,当您在初始实现中调用Response.Redirect时,您将远离ASP.NET MVC设计约定;即使它有效,但设计也不好。

答案 1 :(得分:0)

使用这段代码。它会起作用。

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            PartialViewResult result = new PartialViewResult();
            result.ViewName = "noaccess";


            filterContext.Result = result;
        }