Почему мой ASP.NET Web API ActionFilterAttribute OnActionExecuting не срабатывает?
Я пытаюсь реализовать увиденное здесь: 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;
}
}
Почему этот фильтр действий не будет запускать какие-либо из событий внутри?
Ответы
Ответ 1
Если вы работаете в проекте, это содержит как MVC, так и WebAPI-сборки, можете ли вы проверить, какое пространство имен пространство имен ActionFilterAttribute. Это довольно запутанная причина, по которой есть два ActionFilterAttributes:
- WebAPI: System.Web.Http.Filters
- MVC: System.Web.Http.Mvc
Ответ 2
Ответ выше определенно помог мне - спасти других некоторое время... здесь явно разница.
Стандартные контроллеры 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
Для всех, кто сталкивается с этим, ActionFilterAttribute не срабатывает при вызове YourController.YourAction из вашего UnitTest.
[TestMethod]
public void RevokeSiteAdmin_SessionOver()
{
FakeDbContext db = new FakeDbContext();
YourController controller = new YourController(db);
var result = controller.YourAction();
//Some Assertions
}
В TestMethod выше, любые ActionFilterAttributes на YourController.YourAction не будут вызываться. Однако; если вы вызываете YourController.YourAction из браузера, вызывается ваш ActionFilterAttribute.
Это верно, по крайней мере, для WebApi, но я не знаю, относится ли это к MVC.
Ответ 4
Вот полная реализация:
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);
}
}
}
Ответ 5
Для WebApi вы должны установить Microsoft.AspNet.WebApi.Core из nuget.
Для MVC вы можете использовать System.Web.MVC.
Ответ 6
Моя проблема была намного проще:
Проверьте, что ваш контроллер украшен <actionPreProcessActivitiesAttribute()> _