System.Web.Http.Filters.ActionFilterAttribute 必须与控制器在同一个项目中吗?
System.Web.Http.Filters.ActionFilterAttribute must be in same project as controller?
我有一个 System.Web.Http.ApiController 派生的控制器:
[LoggingFilterApi]
public class BaseController : ApiController
{
public IHttpActionResult Ads();
}
过滤器定义如下:
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace pecom.Common.Filters
{
public class LoggingFilterApiAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext ctx)
{
var msg = ctx.ActionDescriptor.ControllerDescriptor.ControllerType.Name + "." + ctx.ActionDescriptor.ActionName +
"(" + ctx.Request.RequestUri.ToString();
ILog logger = LogManager.GetLogger(ctx.ActionDescriptor.ControllerDescriptor.ControllerType);
logger.Info(msg);
base.OnActionExecuting(ctx);
}
}
}
当 LoggingFilterApiAttribute.cs
是控制器 .csproj
的一部分时,OnActionExecuting
将按预期调用。但是,如果将 LoggingFilterApiAttribute.cs
移动到不同的 .csproj
(以促进代码重用),OnActionExecuting
将 而不是 按预期调用。奇怪。
有人看到了吗?目前我在我们的项目中复制过滤器,这有点不理想。这是 ASP.NET MVC 5.2.
干杯,皮特
我设法通过几个步骤让它工作:
- 创建 MVC 应用程序
- 创建一个空的 class 库
- 使用 nuget
将 MVC 框架添加到 class 库
- 将对 System.Web 的引用添加到 class 库项目
- 将您的代码复制到 class 库的新 class 中
- 出于测试目的删除与记录器相关的代码
- 将 HttpActionContext ctx 替换为 ActionExecutingContext
过滤器上下文
- 将 ctx.Request.RequestUri.ToString() 替换为
filterContext.HttpContext.Request.Url
- 引用 Class 库项目
- 将过滤器添加到家庭控制器
任务完成
您的 Web Api 2 版本很可能不匹配。不管是哪个版本的MVC,你的controller都是WebApi的,所以要注意WebApi相关的程序集
我很确定,如果您在 MVC 项目和 class 库中检查 System.Web.Http
的版本,它们会有所不同,因此发现机制不是能够找到您的自定义过滤器。只需使它们匹配即可解决问题,它应该可以工作。
一个简单的修复方法是在您的 class 库中引用最新的 Web Api 2 包 (Microsoft.AspNet.WebApi.Core
), 和 升级您的 MVC 项目中的相同包以使其匹配(或者如果您愿意,可以通过混淆程序集重定向)。例如,如果您只是将代码复制到 class 库中,然后使用类似 Resharper 的东西来解析引用,它很可能从 GAC 选择了 4.x 版本的 System.Web.Http
,而不是您在此处需要的版本 5.x。
我试过你所做的,它重现了你同样的问题,这个程序解决了它。
我有一个 System.Web.Http.ApiController 派生的控制器:
[LoggingFilterApi]
public class BaseController : ApiController
{
public IHttpActionResult Ads();
}
过滤器定义如下:
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace pecom.Common.Filters
{
public class LoggingFilterApiAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext ctx)
{
var msg = ctx.ActionDescriptor.ControllerDescriptor.ControllerType.Name + "." + ctx.ActionDescriptor.ActionName +
"(" + ctx.Request.RequestUri.ToString();
ILog logger = LogManager.GetLogger(ctx.ActionDescriptor.ControllerDescriptor.ControllerType);
logger.Info(msg);
base.OnActionExecuting(ctx);
}
}
}
当 LoggingFilterApiAttribute.cs
是控制器 .csproj
的一部分时,OnActionExecuting
将按预期调用。但是,如果将 LoggingFilterApiAttribute.cs
移动到不同的 .csproj
(以促进代码重用),OnActionExecuting
将 而不是 按预期调用。奇怪。
有人看到了吗?目前我在我们的项目中复制过滤器,这有点不理想。这是 ASP.NET MVC 5.2.
干杯,皮特
我设法通过几个步骤让它工作:
- 创建 MVC 应用程序
- 创建一个空的 class 库
- 使用 nuget 将 MVC 框架添加到 class 库
- 将对 System.Web 的引用添加到 class 库项目
- 将您的代码复制到 class 库的新 class 中
- 出于测试目的删除与记录器相关的代码
- 将 HttpActionContext ctx 替换为 ActionExecutingContext 过滤器上下文
- 将 ctx.Request.RequestUri.ToString() 替换为 filterContext.HttpContext.Request.Url
- 引用 Class 库项目
- 将过滤器添加到家庭控制器
任务完成
您的 Web Api 2 版本很可能不匹配。不管是哪个版本的MVC,你的controller都是WebApi的,所以要注意WebApi相关的程序集
我很确定,如果您在 MVC 项目和 class 库中检查 System.Web.Http
的版本,它们会有所不同,因此发现机制不是能够找到您的自定义过滤器。只需使它们匹配即可解决问题,它应该可以工作。
一个简单的修复方法是在您的 class 库中引用最新的 Web Api 2 包 (Microsoft.AspNet.WebApi.Core
), 和 升级您的 MVC 项目中的相同包以使其匹配(或者如果您愿意,可以通过混淆程序集重定向)。例如,如果您只是将代码复制到 class 库中,然后使用类似 Resharper 的东西来解析引用,它很可能从 GAC 选择了 4.x 版本的 System.Web.Http
,而不是您在此处需要的版本 5.x。
我试过你所做的,它重现了你同样的问题,这个程序解决了它。