【问题标题】:Session variable becomes null in action filter会话变量在操作过滤器中变为空
【发布时间】:2015-11-30 17:13:53
【问题描述】:

如果用户的电子邮件地址未经确认,我正在尝试创建一个操作过滤器以将用户重定向到 ConfirmEmail 操作。在我的控制器中,我设置了会话变量,在我的操作过滤器中,我检查了会话变量是否为空。

    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    { 
          // some code here

          if (!await UserManager.IsEmailConfirmedAsync(user.Id))
          {
            Session["ConfirmEmail"] = "true";
          }

         // some code here
     }

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

我不确定为什么操作过滤器无法读取会话。我应该使用其他方法来实施此检查吗?

编辑

我找到了问题!在我的代码中(在我设置会话之前,我有以下内容) Session.Clear();Session.Abandon();。我不认为这会是一个问题,因为它是在我设置会话之前调用的,但我想它是

【问题讨论】:

  • 作为在黑暗中的野刺,将 if 语句更改为:if (!await UserManager.IsEmailConfirmedAsync(user.Id).ConfigureAwait(false)) 是否有效?
  • 我知道我的 if 语句不是问题,因为当我调试时我看到它进入了 if 语句,并且 Session["ConfirmEmail"] 实际上等于 true。但是,一旦它进入我的过滤器类,filterContext.HttpContext.Session["ConfirmEmail"] 是错误的
  • @EitanK - 是false 还是"false"?您将会话变量设置为字符串"true",但希望类型转换(bool)Session[...] 能够工作——它不会。您需要将变量设置为布尔值true 或使用System.Convert.ToBoolean(...) 进行转换。
  • @Igor 我修复了那部分谢谢。但是,它永远不会达到这一点,因为操作过滤器认为 Session["ConfirmEmai"] 为空
  • 您是否尝试过将某些内容放入控制器的会话中,然后在操作过滤器中读取它,而无需任何更多逻辑(没有 if 或 cast)?你必须把[SessionState(SessionStateBehavior.Required)] 放在你的控制器上

标签: c# asp.net asp.net-mvc session session-variables


【解决方案1】:

我觉得你的逻辑有点不对劲

  1. 尝试传递一个布尔值而不是字符串值“true”

        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!await UserManager<>.IsEmailConfirmedAsync(user.Id))
            {
                Session["ConfirmEmail"] = true;
                RedirectToAction("ConfirmEmail");
            }
        }
    
  2. 您的 OnActionExecuting 应该使用受保护的访问修饰符

  3. 你的 if 语句正在检查 if !true 而不是仅仅检查 true

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["ConfirmEmail"] != null)
        {
            if (filterContext.HttpContext.Session["ConfirmEmail"] is bool && (bool) filterContext.HttpContext.Session["ConfirmEmail"])
            {
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary
                    {
                        {"controller", "Account"},
                        {"action", "ConfirmEmail"}
                    });
            }
        }
    }
    

希望这会有所帮助。

【讨论】:

  • 问题是,无论是字符串还是布尔值,当调试器进入我的过滤器类时,传递的任何值都会变为 null。所以它甚至没有进入 OnActionExecuting 方法中的第二个 if 语句。此外,当我更改对受保护的访问权限时,我收到此错误消息:cannot change access modifiers when overriding 'public' inherited member 'System.Web.Mvc.ActionFilterAttribute.OnActionExecuting
猜你喜欢
  • 2023-03-11
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 2016-11-11
相关资源
最近更新 更多