C# 为什么我的ASP.NET Web API ActionFilterAttribute OnActionExecuting没有启动?

C# 为什么我的ASP.NET Web API ActionFilterAttribute OnActionExecuting没有启动?,c#,asp.net-web-api,action-filter,actionfilterattribute,C#,Asp.net Web Api,Action Filter,Actionfilterattribute,我试图实现这里看到的内容:但是我的NhSessionManagementAttribute有问题 我已经在我的OnActionExecuting(HttpActionContext-actionContext)上设置了断点,以查看函数是否被调用过——实际上没有 我仔细检查了我的global.asax.cs文件,发现我实际上正在注册ActionFilter: GlobalConfiguration.Configuration.Filters.Add(new NhSessionManagementA

我试图实现这里看到的内容:但是我的
NhSessionManagementAttribute
有问题

我已经在我的
OnActionExecuting(HttpActionContext-actionContext)
上设置了断点,以查看函数是否被调用过——实际上没有

我仔细检查了我的
global.asax.cs
文件,发现我实际上正在注册
ActionFilter

GlobalConfiguration.Configuration.Filters.Add(new NhSessionManagementAttribute());
我还用属性修饰了我的控制器类本身及其操作,但没有效果:

public class ClientsController : ApiController {
    static readonly ClientRepository repository = new ClientRepository();

    [NhSessionManagement]
    public IEnumerable<Client> GetAllClients() {
        return repository.GetAll();
    }

    [NhSessionManagement]
    public Client GetClient(int id) {
        Client client = repository.Get(id);
        if (client == null) {
            throw new HttpResponseException(
                new HttpResponseMessage(HttpStatusCode.NotFound)
            );
        }
        return client;
    }
}
公共类客户端控制器:ApiController{
静态只读ClientRepository repository=new ClientRepository();
[会议管理]
public IEnumerable GetAllClient(){
返回repository.GetAll();
}
[会议管理]
公共客户端GetClient(int-id){
Client=repository.Get(id);
if(客户端==null){
抛出新的HttpResponseException(
新的HttpResponseMessage(HttpStatusCode.NotFound)
);
}
返回客户;
}
}

为什么此操作筛选器不会触发其中的任何事件?

如果您在一个同时包含MVC和WebAPI组件的项目中工作,请检查ActionFilterAttribute的命名空间是什么。这相当令人困惑,因为在这两种情况下都有两种ActionFilterAttribute:

  • WebAPI:System.Web.Http.Filters
  • MVC:System.Web.Http.MVC

以上的答案肯定对我有所帮助-为其他人节省了一些时间。。。这就是明显的区别

标准MVC控制器使用:

// System.Web.Mvc
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);
}
// System.Web.Http.Filters;
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
    base.OnActionExecuted(actionExecutedContext);
}
ODataHTTP控制器使用:

// System.Web.Mvc
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);
}
// System.Web.Http.Filters;
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
    base.OnActionExecuted(actionExecutedContext);
}

对于遇到此问题的任何其他人,当从UnitTest调用controller.YourAction时,ActionFilterAttribute将不会激发

[TestMethod]
public void RevokeSiteAdmin_SessionOver()
{
    FakeDbContext db = new FakeDbContext();

    YourController controller = new YourController(db);
    var result = controller.YourAction();

    //Some Assertions
}
在上面的TestMethod中,不会调用Controller.YourAction上的任何ActionFilterAttributes。然而;如果从浏览器调用controller.YourAction,将调用ActionFilterAttribute


至少WebApi是这样,但我不知道它是否适用于MVC。

以下是完整的实现:

public class AllowCrossSiteJsonAttribute : System.Web.Mvc.ActionFilterAttribute
{
    public override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext != null && filterContext.HttpContext.Response != null && filterContext.HttpContext.Request != null && filterContext.HttpContext.Request.UrlReferrer != null)
        {
            var allowedCrossDomains = TypeSafeConfigurationManager.GetValueString("allowedCrossDomains", "none");
            var allowedHosts = allowedCrossDomains.Split(',');

            var requestHost =  filterContext.HttpContext.Request.UrlReferrer.GetLeftPart(UriPartial.Authority);
            if (allowedHosts.Contains(requestHost.ToLower()))
            {
                filterContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", requestHost);
            }
        }

        base.OnActionExecuted(filterContext);
    }
}
public class AllowCrossSiteJsonForWebApiAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null && actionExecutedContext.Request != null &&
            actionExecutedContext.Request.Headers.Referrer != null)
        {
            var allowedCrossDomains = TypeSafeConfigurationManager.GetValueString("allowedCrossDomains", "none");
            var allowedHosts = allowedCrossDomains.Split(',').ToList();

            var requestHost = actionExecutedContext.Request.Headers.Referrer.GetLeftPart(UriPartial.Authority);

            if (allowedHosts.Contains(requestHost.ToLower()))
            {
                actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", requestHost);
            }

            base.OnActionExecuted(actionExecutedContext);
        }
    }
}

对于WebApi,您应该从nuget安装Microsoft.AspNet.WebApi.Core。
对于MVC,您可以使用System.Web.MVC。

我的问题要简单得多:


检查您的控制器是否装饰有
\u

对于WebAPI,应该使用System.Web.Http.Mvc filter属性,对吗?我一直在试图找出我的ActionFilter在过去几个小时内无法工作的原因。谢谢特洛伊!:)WebApi的ActionFilterAttribute位于System.Web.Http.dll assembly.MVC中:System.Web.Http.MVC-->System.Web.MVC在某些ASP.NET MVC版本中,我仍然感到困惑。对于WebAPI,为什么System.Web.Http.Filters.ActionFilterAttribute不是合适的选择?答案只是说检查名称空间并声明有两个名称空间。它没有解释为什么不使用WebAPI,System.Web.Http.Filters也适用于WebAPI。如果使用Ninject,那么需要注意的是,对于Mvc和Http,过滤器绑定也位于不同的库中。Mvc-Ninject.Web.Mvc WebApi/Http-Ninject.Web.WebApi实际上,Http控制器使用的应该显示OnActionExecuting(HttpActionContext HttpActionContext),然后调用base.OnActionExecuting(HttpActionContext)。OnActionExecuted()也可用。