1

我不确定这是否是解决我需要解决的问题的正确方法......但是在我创建的 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

4 回答 4

4

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

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

public override void OnActionExecuting(HttpActionContext actionContext)
{
    //your logic here
    base.OnActionExecuting(actionContext);
}
于 2015-08-04T15:51:50.430 回答
1

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

于 2014-03-20T20:17:02.950 回答
1

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

if (filterContext.Controller.TempData["MyActionFilterAttribute_OnActionExecuting"] == null)
{
    filterContext.Controller.TempData["MyActionFilterAttribute_OnActionExecuting"] = true;
}
于 2014-03-20T20:27:23.323 回答
1

Old question, but I just dealt with this so I thought I'd throw in my answer. After some investigating I disovered this was only happening on endpoints that returned a view (i.e. return View()). The only endpoints that had multiple OnActionExecuting fired were HTML views that were composed of partial views (i.e. return PartialView(...)), so a single request was "executing" multiple times.

I was applying my ActionFilterAttribute globally to all endpoints, which was working correctly on all other endpoints except for the view endpoints I just described. The solution was to create an additional attribute applied conditionally to the partial view endpoints.

// 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
    }
  }
}

And then on my partial view endpoints

[HttpGet]
[AllowAnonymous]
[IgnoreGlobalFilter] //HERE this keeps the attribute from firing again
public ActionResult GetPartialView()
{
  // partial view logic
  return PartialView();
}
于 2019-03-29T17:32:02.240 回答