为什么我的ASP.NET Web API ActionFilterAttribute OnActionExecuting无法启动?


72

我正在尝试实施此处看到的内容:http : //www.piotrwalat.net/nhibernate-session-management-in-asp-net-web-api/但我的出现了问题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;
    }
}

为什么此动作过滤器不会触发其中的任何事件?

Answers:


169

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

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

1
对于WebAPI,应该使用System.Web.Http.Mvc筛选器属性,对吗?
neontapir

我一直在试图弄清楚为什么我的ActionFilter在最近几个小时内无法正常工作。谢谢特洛伊!:)
divyanshm

3
WebApi的ActionFilterAttribute在System.Web.Http.dll程序集中。
Frode Lillerud 2013年

4
MVC:某些ASP.NET MVC版本中的System.Web.Http.Mvc-> System.Web.Mvc
boj

4
我还是很困惑。对于WebAPI,为什么System.Web.Http.Filters.ActionFilterAttribute不是合适的选择?答案只是说要检查名称空间,并指出有两个。它没有解释为什么您不使用WebAPI。
AaronLS

34

上面的答案肯定对我有所帮助-节省了一些时间...这显然是与众不同的。

标准MVC控制器使用:

// System.Web.Mvc
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);
}

OData HTTP控制器使用:

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

3
而且System.Web.Http.Filters也适用于WebApi。如果使用Ninject,请务必注意,Mvc和Http的过滤器绑定也位于不同的库中。Mvc-Ninject.Web.Mvc WebApi / Http-Ninject.Web.WebApi
肯特·费里巴赫

1
实际上,使用的HTTP控制器应显示OnActionExecuting(HttpActionContext httpActionContext),然后调用base.OnActionExecuting(httpActionContext)。OnActionExecuted()也可用。
GarDavis

6

对于遇到此问题的其他任何人,从UnitTest调用YourController.YourAction时均不会触发ActionFilterAttribute。

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

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

    //Some Assertions
}

在上面的TestMethod中,不​​会调用YourController.YourAction上的任何ActionFilterAttributes。然而; 如果从浏览器调用YourController.YourAction,则将调用ActionFilterAttribute。

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


1

这是完整的实现:

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);
        }
    }
}

0

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


0

我的问题要简单得多:

检查您的控制器是否装饰有 <actionPreProcessActivitiesAttribute()> _

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.