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.

干杯,皮特

我设法通过几个步骤让它工作:

  1. 创建 MVC 应用程序
  2. 创建一个空的 class 库
  3. 使用 nuget
  4. 将 MVC 框架添加到 class 库
  5. 将对 System.Web 的引用添加到 class 库项目
  6. 将您的代码复制到 class 库的新 class 中
  7. 出于测试目的删除与记录器相关的代码
  8. 将 HttpActionContext ctx 替换为 ActionExecutingContext 过滤器上下文
  9. 将 ctx.Request.RequestUri.ToString() 替换为 filterContext.HttpContext.Request.Url
  10. 引用 Class 库项目
  11. 将过滤器添加到家庭控制器

任务完成

您的 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。

我试过你所做的,它重现了你同样的问题,这个程序解决了它。