【问题标题】:Process cookies before any controller action is invoked in ASP.NET MVC在 ASP.NET MVC 中调用任何控制器操作之前处理 cookie
【发布时间】:2011-07-13 14:49:30
【问题描述】:

在执行任何控制器操作之前,我可以将一些将执行的代码放在哪里?

我正在尝试替换默认的 ASP.NET 会话,我需要在任何控制器操作发生之前执行此操作: 获取 cookie 集合并检查我是否有没有 cookie 的新访问者 - 我会添加新的“会话 ID”cookie,该 cookie 将比控制器可用。否则(如果已经有一些“会话 ID”cookie)我不会做任何事情。

我在哪里可以放置执行此操作的代码?

【问题讨论】:

    标签: c# .net asp.net asp.net-mvc cookies


    【解决方案1】:

    有很多地方可以做到这一点,我想说最好的地方是在 ActionFilter 中,覆盖 OnActionExecuting 事件。如果您希望它首先发生,那么您需要在应用它时添加 Order 设置。

    如果您希望所有您的控制器都拥有它,那么您可以将该过滤器应用于基类,或者只是覆盖基类的 OnActionExecuting 方法。

    附带说明,为了最大程度的可测试性,您可能应该让您的 not 直接访问请求中的 cookie 集合;该信息(如果需要)应作为参数或控制器上的属性进入操作方法,您可以在测试中设置。

    如果您需要在 OnActionExecuting 之前连接到生命周期(出于任何原因),您也可以创建一个自定义 ControllerFactory,但根据您的描述,我认为这可能有点矫枉过正。

    【讨论】:

    • 抱歉劫持,但你让我思考。如果出于某种原因,我想将 cookie 值拉入路由值以用作操作方法的参数,我可能想在新的基本控制器的 OnActionExecuting 中执行此操作?或者在决定调用哪个动作方法时已经太迟了?
    • @patridge:在我的情况下,我不需要操作或更改将要调用的操作方法。我只需要在 Cookies 集合中添加一些东西......但也许你在问一般情况下(比您可能考虑创建自己的问题)
    • @patridge> afaik,在这种情况下,您将注册一个自定义 IValueProvider,以提取它们并让它们用于路由和模型绑定(这不是积极的,但很确定)。您也可以使用 ActionSelectionAttribute 来做您正在寻找的事情,但是对于任何不平凡的事情来说,它们比它们更有价值。
    【解决方案2】:

    自定义IHttpModule 可以解决问题。

    【讨论】:

    • 我是否可以从IHttpModule 实现类访问Request 属性,或者是否有任何其他方法可以从实现类中获取HttpRequest 的实例?我需要它才能收集 cookie。
    • 看起来你会的。在来自 MSDN 链接的示例中,他们通过事件源参数在实现中得到它。例如,在他们的HttpApplication.BeginRequest 处理程序中:((HttpApplication)source).Context.Request
    【解决方案3】:

    ASP.NET MVC 3 现在具有将为每个控制器运行的全局操作过滤器:

    Scott Guthrie 的概述:http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx
    MSDN 关于过滤器类型的详细信息:http://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx

    【讨论】:

      【解决方案4】:

      我在 Global.asax.cs 中做

      protected void Application_BeginRequest(object sender, EventArgs e)
      {
                  var c = Request.Cookies["lang"];
      ...
      }
      

      【讨论】:

      【解决方案5】:

      在您的 global.asax 上:

       protected void Application_Start()
              {
                  GlobalConfiguration.Configure(WebApiConfig.Register);
                  RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
              }
      
      public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
              {
                  filters.Add(new CredentialsActionFilter());
              }
      

      CredentialsActionFilter 类:

       public override void OnActionExecuting(HttpActionContext actionContext)
              {
                  var cookies = actionContext.Request.Headers.GetCookies("credentials").FirstOrDefault();
                  string username = cookies.Cookies.Where(c => c.Name == "username").FirstOrDefault().Value;
                  actionContext.Request.Properties.Add("username", username); // so you can access the value from within your actions
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多