OnActionExecuting多次触发

时间:2014-03-20 19:21:14

标签: asp.net-mvc onactionexecuting

我不确定这是否是解决我需要解决的问题的正确方法...但是在我创建的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?动作过滤器用于多个控制器。

4 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

一个老问题,但是我只是处理了这个问题,所以我想我应该回答一下。经过一番调查后,我发现这只发生在返回视图的端点(即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();
}