为什么我的 ASP.NET Web API ActionFilterAttribute OnActionExecting 没有激活?

我正在尝试实现这里看到的: 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;
}
}

为什么这个操作过滤器不触发任何内部事件?

57097 次浏览

如果您在一个同时包含 MVC 和 WebAPI 程序集的项目中工作,您可以检查 ActionFilterAttribute 的名称空间是什么吗。这是相当混乱的,因为这两个属性下面都有两个 ActionFilterAttritribute:

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

上面的答案确实帮助了我——为其他人节省了一些时间... ... 这里就是明确的区别。

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

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

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


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


//Some Assertions
}

在上面的 TestMethod 中,YourController 上的任何 ActionFilterAttritribute。你的行动将不会被召唤。但是,如果调用 YourController。从浏览器调用“您的操作”时,将调用 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。

我的问题要简单得多:

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