9

我已经覆盖了控制器检查某些会话数据是否存在。这个数据是仓库正常工作所必需的,所以如果它不存在,那么在检查用户应该注销之后。从控制器重定向初始化不起作用

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类型的“用户”,以便可以像用户用户名那样在构造函数中访问它?

回答

12

请考虑使用自定义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的(或者它的子类)处理所有的请求。

+0

我明白原理,但看起来有点不切实际。我不能将它作为全局过滤器,因为有公共应用领域,然后我必须将它应用于需要它的区域内的每个操作?有没有其他方式可以在初始化之后打破Controller的加载并将其发送给另一个Controller的另一个操作? – Zaak

+0

您可以将该属性应用于控制器,并将其应用于该控制器或控制器基类中的每个动作,然后该动作也将应用于每个派生类动作! –

+0

嗯,这种方式仍然没有解决我必须设置一次的事实。似乎通过这种方式通过FilterAttribute处理事件会在每次执行操作时设置它,而不是仅在Controller实例化时才执行操作。 – Zaak

2

只需通过在基类中重写OnActionExcuting来实现您的解决方案。然后,您可以在“动作过滤器”中执行您所能做的一切。像这样:

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"})); 
} 

略去了一些代码。

我尝试了这两种方法,并发现通过操作过滤器来实现它更复杂,这是由于我有依赖注入要求。你可以做到这一点,但感觉基类方法更清晰一些。我还希望在基类上设置一些属性,以使控制器方法可以使用一些标准对象来保存重复代码,这些代码将添加到操作中。基类方法使得这很简单。

我要补充的一点是我并不是说这是一个很好的认证/安全方法,我只是从执行操作之前想要执行某些操作/验证的角度来看待这个问题,还要在控制器实例上设置一些预填充数据,以遵循DRY原则。

希望它有帮助。