从控制器重定向初始化不起作用

时间:2011-11-22 11:19:22

标签: asp.net-mvc asp.net-mvc-3 controller asp.net-membership session-variables

我有控制器的覆盖,检查是否存在某些会话数据。存储库正常工作需要此数据,因此如果不存在则在检查后应该注销用户。

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    base.Initialize(requestContext);
    if (Session["CompanyID"] != null)
    {
        repo.CompanyID = (long)Session["CompanyID"];
    }
    else
    {
        RedirectToAction("LogOff", "Account");
    }
}

我的代码如下所示,但即使调用RedirectToAction,控制器仍会打开默认操作,用户也不会注销。 你能建议如何处理这个问题吗?

我正在以这种方式使用这个会话数据,因为这是我所知道的第一个地方,在这里我可以检查这个特定数据是否存在。它是在用户登录时写的。

此数据是用户在数据库中的一部分。我已经成为自定义成员资格和角色提供者。有没有办法以某种方式将此数据添加到MembershipUser类型的“User”,以便可以在构造函数中访问,如用户用户名?

2 个答案:

答案 0 :(得分:14)

请考虑使用自定义ActionFilter

public class HasCompanyIdAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["CompanyID"] == null)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"}));
        }
    }
}

然后可以这样应用:

[HasCompanyId]
public class MyController : Controller 
{
    public ActionResult SomeAction()
    {
        return View();
    }
}

这将为MyController(或它的子类)处理的所有请求应用该属性。

答案 1 :(得分:2)

只需通过覆盖基类中的OnActionExcuting来实现您的解决方案。然后,您可以在Action Filter中执行所有操作。像这样:

public void OnActionExecuting(ActionExecutingContext filterContext){
  if (filterContext.HttpContext.Session["CompanyID"] != null)
     repo.CompanyID = (long)filterContext.HttpContext.Session["CompanyID"];
  else
     filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"}));
}

为简洁起见,省略了一些代码。

我尝试了这两种方法,并且发现通过动作过滤器实现它更复杂,因为我有依赖注入要求。您可以采用任何一种方式,但感觉基类方法更清晰一些。我还想在基类上设置一些属性,以便为控制器方法提供一些标准对象,以保存DEV正在添加到操作中的重复代码。基类方法使这很容易。

我要补充的一个警告是,我并不是说这是一种很好的身份验证/安全方法,我纯粹是从想要在执行操作之前执行某些操作/验证的角度来看这个。在控制器实例上设置一些预先填充的数据以遵循DRY原则。

希望它有所帮助。