我的MVC 3 web应用程序有不同的部分,需要检查用户是用户还是管理员,他们都可以访问相同的页面,除有些页面有控制器(按钮和文本框),只有管理员才能看到。我这样做,检查通过将用户的访问级别到我的视图模型,并做了检查:自定义属性重定向导致“子动作不允许执行重定向动作”错误
@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,这也不起作用。
我想过,但主要很少重新加载。然而,里面的部分经常使用。所以我这样做,以便如果用户超时并返回,则必须对部分进行检查,因为主视图不会再被触发?我还能怎么做?我希望将Response.Redirect更改为RedirectToRouteResult,但这与儿童操作无法重定向的问题相同。 – LanFeusT 2011-05-06 01:00:41
局域网,在这种情况下,我会做的是返回一个不同的局部视图,指示用户登录(您可以在返回时按名称指定视图);无需重新设计您的应用程序,这是您可以尝试的一件简单的事情。 – Aaronontheweb 2011-05-06 01:11:10
你的第二个答案是我支持的那个:D – Aaronontheweb 2011-05-06 01:11:29