我有控制器的覆盖,检查是否存在某些会话数据。存储库正常工作需要此数据,因此如果不存在则在检查后应该注销用户。
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”,以便可以在构造函数中访问,如用户用户名?
答案 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原则。
希望它有所帮助。