asp.net mvc动作的奇怪行为过滤了AttributeUsage

时间:2022-11-01 10:59:48

I have an action filter with the following signature

我有一个带有以下签名的动作过滤器

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class UnitOfWorkAttribute : ActionFilterAttribute

According to MSDN:

根据MSDN:

The AllowMultiple property indicates whether multiple instances of your attribute can exist on an element. If set to true, multiple instances are allowed; if set to false (the default), only one instance is allowed.

AllowMultiple属性指示属性的多个实例是否可以存在于元素上。如果设置为true,则允许多个实例;如果设置为false(默认值),则只允许一个实例。

In MVC the behaviour seems a bit strange. When I decorated an action with this attribute, I found that the OnActionExecuting method of the filter was executed twice.

在MVC中,行为似乎有点奇怪。当我使用此属性修饰动作时,我发现过滤器的OnActionExecuting方法执行了两次。

The filter was only declared on the action, not on the controller, and I had cleared any global filters. Could someone explain this behaviour?

过滤器仅在操作上声明,而不是在控制器上声明,并且我已清除任何全局过滤器。有人可以解释这种行为吗?

2 个解决方案

#1


29  

I encountered the same problem. (I installed a global filter (just once) and discovered that its IActionFilter and IResultFilter methods were being called twice for each request. The filterContext.HttpContext object being passed to these methods was exactly the same for both calls.)

我遇到了同样的问题。 (我安装了一个全局过滤器(只有一次)并发现每个请求都调用了两次IActionFilter和IResultFilter方法。传递给这些方法的filterContext.HttpContext对象对于两个调用完全相同。)

This turned out to be due to using Html.Action in the view. It appears (from looking at the call stack) that calling Html.Action reentrantly processes the child action method (during the processing of the initial action method) and the filters get invoked for both.

原来这是由于在视图中使用Html.Action。看起来(从查看调用堆栈)看来,调用Html.Action会重新处理子操作方法(在处理初始操作方法期间),并为两者调用过滤器。

You can detect this situation by checking the filterContext.IsChildAction property.

您可以通过检查filterContext.IsChildAction属性来检测这种情况。

#2


0  

I've had the OnActionExecuting method from my custom action filter class executing twice too.

我的自定义操作过滤器类也执行了两次OnActionExecuting方法。

At some point I added this to my Application_Start method in the global.asax.cs file:

在某些时候,我将它添加到global.asax.cs文件中的Application_Start方法:

GlobalConfiguration.Configuration.Filters.Add(new MyCustomActionFilter());

Apparently, my action filter was already added to the Filters collection which was leading to the double call to OnActionExecuting and OnActionExecuted. So that line in the applicaton_start was not needed.

显然,我的动作过滤器已经添加到Filters集合中,这导致对OnActionExecuting和OnActionExecuted的双重调用。因此不需要applicaton_start中的那一行。

#1


29  

I encountered the same problem. (I installed a global filter (just once) and discovered that its IActionFilter and IResultFilter methods were being called twice for each request. The filterContext.HttpContext object being passed to these methods was exactly the same for both calls.)

我遇到了同样的问题。 (我安装了一个全局过滤器(只有一次)并发现每个请求都调用了两次IActionFilter和IResultFilter方法。传递给这些方法的filterContext.HttpContext对象对于两个调用完全相同。)

This turned out to be due to using Html.Action in the view. It appears (from looking at the call stack) that calling Html.Action reentrantly processes the child action method (during the processing of the initial action method) and the filters get invoked for both.

原来这是由于在视图中使用Html.Action。看起来(从查看调用堆栈)看来,调用Html.Action会重新处理子操作方法(在处理初始操作方法期间),并为两者调用过滤器。

You can detect this situation by checking the filterContext.IsChildAction property.

您可以通过检查filterContext.IsChildAction属性来检测这种情况。

#2


0  

I've had the OnActionExecuting method from my custom action filter class executing twice too.

我的自定义操作过滤器类也执行了两次OnActionExecuting方法。

At some point I added this to my Application_Start method in the global.asax.cs file:

在某些时候,我将它添加到global.asax.cs文件中的Application_Start方法:

GlobalConfiguration.Configuration.Filters.Add(new MyCustomActionFilter());

Apparently, my action filter was already added to the Filters collection which was leading to the double call to OnActionExecuting and OnActionExecuted. So that line in the applicaton_start was not needed.

显然,我的动作过滤器已经添加到Filters集合中,这导致对OnActionExecuting和OnActionExecuted的双重调用。因此不需要applicaton_start中的那一行。