asp.net mvc 操作过滤器 AttributeUsage 的奇怪行为

编程代码

1个回答

写回答

ASP.NET MVC中的操作过滤器是一种强大的功能,它可以在控制器和操作方法执行前后进行一些额外的处理。AttributeUsage是一个用于自定义属性的特性,它可以限制属性的使用方式。然而,有时候AttributeUsage的行为可能会让人感到困惑,下面我会通过一个奇怪的案例来说明这个问题。

首先,让我们来看一个简单的示例代码,以便更好地理解这个问题:

csharp

using System;

using System.Web.Mvc;

namespace MvcApp.Filters

{

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]

public class MyFilterAttribute : ActionFilterAttribute

{

public override void OnActionExecuting(ActionExecutingContext filterContext)

{

// 在操作方法执行前执行一些逻辑

Console.WriteLine("Executing before action...");

}

public override void OnActionExecuted(ActionExecutedContext filterContext)

{

// 在操作方法执行后执行一些逻辑

Console.WriteLine("Executing after action...");

}

}

}

namespace MvcApp.Controllers

{

public class HomeController : Controller

{

[MyFilter]

public ActionResult Index()

{

return View();

}

}

}

上述代码定义了一个自定义的操作过滤器MyFilterAttribute,它继承自ActionFilterAttribute。然后,在HomeController的Index方法上添加了一个MyFilter特性。

这个特性在操作方法执行前后都会执行一些逻辑,并在控制台上输出一些信息。

接下来,我们在Global.asax.cs中注册这个过滤器:

csharp

using System.Web.Mvc;

using System.Web.Routing;

using MvcApp.Filters;

namespace MvcApp

{

public class MvcApplication : System.Web.HttpApplication

{

protected void Application_Start()

{

// 注册过滤器

GlobalFilters.Filters.Add(new MyFilterAttribute());

RouteConfig.RegisterRoutes(RouteTable.Routes);

}

}

}

现在,我们运行这个程序,然后访问HomeController的Index方法,会发现输出的信息是:

Executing before action...

Executing after action...

这是符合预期的,因为我们在HomeController的Index方法上添加了MyFilter特性,所以过滤器会在方法执行前后分别被调用。

然而,如果我们将MyFilter特性的AttributeUsage特性修改为以下内容:

csharp

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]

然后再次运行程序,会发现输出的信息变成了:

Executing before action...

这是一个奇怪的行为,按照我们的预期,过滤器应该在方法执行前后都被调用,但实际上只有在方法执行前被调用了。

为了解释这个问题,我们需要了解AttributeUsage的作用。AttributeUsage特性可以用来限制自定义属性的使用方式,例如指定它可以应用在哪些目标上,是否允许多次应用等。在上面的例子中,我们将AttributeTargets修改为了AttributeTargets.Method | AttributeTargets.Class,这表示我们的特性可以应用在类和方法上。

然而,由于我们只在HomeController的Index方法上添加了MyFilter特性,所以在该方法执行前后调用过滤器是符合预期的。而在其他方法上未添加该特性,所以过滤器不会被调用。

因此,我们可以得出,AttributeUsage特性对于类级别的特性是不生效的,只对方法级别的特性生效。

在ASP.NET MVC中,AttributeUsage特性对于类级别的操作过滤器是不生效的,只对方法级别的操作过滤器生效。这可能是一个奇怪的行为,但我们可以通过仔细理解AttributeUsage的作用来解释这个问题。

在实际开发中,我们需要注意AttributeUsage的使用方式,以确保自定义属性的行为与预期一致。同时,对于类级别的操作过滤器,我们可以考虑使用其他方式来实现相同的功能,例如基类或接口的方式,来确保过滤器在整个控制器类范围内生效。

举报有用(4)分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号