System.Web.Http.Filters.ActionFilterAttribute必须与控制器位于同一个项目中?

时间:2015-03-27 15:34:40

标签: c# asp.net-mvc asp.net-web-api

我有一个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。

干杯,皮特

2 个答案:

答案 0 :(得分:5)

您很可能在Web Api 2版本中存在不匹配。无论哪个版本的MVC,你的控制器都是Web Api,所以你必须注意Web Api相关的程序集。

我非常确定,如果您在MVC项目和类库中检查System.Web.Http的版本,它们会有所不同,因此发现机制无法找到您的自定义过滤器只需通过使问题匹配来解决问题就可以解决问题。

解决这个问题的一个简单方法是在类库中引用最新的Web Api 2包(Microsoft.AspNet.WebApi.Core)来升级MVC项目中的相同包以使它们成为可能匹配(或者如果您愿意,可以通过混淆程序集重定向)。例如,如果您只是将代码复制到类库中,然后使用Resharper之类的东西来解析引用,那么很可能从GAC中选择System.Web.Http版本4.x而不是版本5.x你需要的。

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

答案 1 :(得分:1)

我设法让它在几个步骤中完成:

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