【问题标题】:OnActionExecuting fires multiple timesOnActionExecuting 多次触发
【发布时间】:2019-03-30 01:32:02
【问题描述】:

我不确定这是否是解决我需要解决的问题的正确方法......但是在我创建的 OnActionExecuting 操作过滤器中,我设置了一个具有各种值的 cookie。其中一个值用于确定用户是否是第一次访问该网站。如果他们是新访客,那么我会在 ViewBag 中设置一些数据,以便在我的视图中显示这些数据。

我遇到的问题是,在我的一些控制器操作中,我执行了 RedirectToAction。结果是 OnActionExecuting 被触发两次,一次用于原始操作,第二次用于触发新操作。

<HttpGet()>
Function Index(ByVal PageID As String) As ActionResult

    Dim wo As WebPage = Nothing

    Try
        wp = WebPages.GetWebPage(PageID)
    Catch sqlex As SqlException
        Throw
    Catch ex As Exception
           Return RedirectToAction("Index", New With {.PageID = "Home"})
       End If
    End Try

    Return View("WebPage", wp)

End Function

这是一个典型的例子。我有一个数据驱动的网站,它根据指定的 PageID 从数据库中获取网页。如果在数据库中找不到该页面,我将用户重定向到主页。

无论如何都可以防止双重触发还是有更好的方法来设置cookie?动作过滤器用于多个控制器。

【问题讨论】:

  • 我实际上决定另一种方法是将我的代码更改为 OnActionExecuted,然后检查结果是否为视图结果。例如。 If TypeOf filterContext.Result Is ViewResult Then... 这似乎解决了我的代码只触发一次的问题。

标签: asp.net-mvc onactionexecuting


【解决方案1】:

有同样的问题。通过覆盖属性 AllowMultiple 解决:

public override bool AllowMultiple { get { return false; } }

public override void OnActionExecuting(HttpActionContext actionContext)
{
    //your logic here
    base.OnActionExecuting(actionContext);
}

【讨论】:

    【解决方案2】:

    您可以在首次执行时将一些标志值保存到控制器的TempData 集合中,如果出现此值,则跳过过滤器逻辑:

    if (filterContext.Controller.TempData["MyActionFilterAttribute_OnActionExecuting"] == null)
    {
        filterContext.Controller.TempData["MyActionFilterAttribute_OnActionExecuting"] = true;
    }
    

    【讨论】:

      【解决方案3】:

      您可以返回实际操作,而不是重定向到新操作。这样,您就不会引起 http-request,从而不会触发 onactionexecuting(我相信)

      【讨论】:

      • So: Function Index(ByVal PageID As String) As ActionResult Dim wo As WebPage = Nothing Try wp = WebPages.GetWebPage(PageID) Catch sqlex As SqlException Throw Catch ex As Exception Return Index("Home") End If End Try Return View("WebPage", wp) End Function
      • 谢谢,这个例子中更简单的方法是设置 wp = WebPages.GetWebPage("Home") 然后调用它应该调用的视图。
      【解决方案4】:

      老问题,但我刚刚处理了这个问题,所以我想我会回答。经过一番调查,我发现这只发生在返回视图的端点上(即return View())。触发多个OnActionExecuting 的唯一端点是由部分视图(即return PartialView(...))组成的HTML 视图,因此单个请求会“执行”多次。

      我将我的 ActionFilterAttribute 全局应用于所有端点,除了我刚才描述的视图端点之外,它在所有其他端点上都可以正常工作。解决方案是创建一个附加属性,有条件地应用于局部视图端点。

      // Used specifically to ignore the GlobalFilterAttribute filter on an endpoint
      public class IgnoreGlobalFilterAttribute : Attribute {  }
      
      public class GlobalFilterAttribute : ActionFilterAttribute
      {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
          // Does not apply to endpoints decorated with Ignore attribute
          if (!filterContext.ActionDescriptor.GetCustomAttributes(typeof(IgnoreGlobalFilterAttribute), false).Any())
          {
            // ... attribute logic here
          }
        }
      }
      

      然后在我的局部视图端点上

      [HttpGet]
      [AllowAnonymous]
      [IgnoreGlobalFilter] //HERE this keeps the attribute from firing again
      public ActionResult GetPartialView()
      {
        // partial view logic
        return PartialView();
      }
      

      【讨论】:

        猜你喜欢
        • 2015-09-13
        • 1970-01-01
        • 1970-01-01
        • 2018-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多