75

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

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

4

6 回答 6

178

如果您在一个同时包含 MVC 和 WebAPI 程序集的项目中工作,您能否检查一下 ActionFilterAttribute 的命名空间是什么命名空间。这相当令人困惑,因为两者下都有两个 ActionFilterAttributes:

  • WebAPI:System.Web.Http.Filters
  • MVC:系统.Web.Http.Mvc
于 2012-10-21T06:12:07.080 回答
38

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

标准 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);
}
于 2013-03-26T03:35:55.020 回答
7

对于遇到此问题的其他任何人,从 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。

于 2015-06-25T18:02:39.203 回答
2

这是完整的实现:

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);
        }
    }
}
于 2016-02-04T12:02:13.653 回答
0

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

于 2016-03-07T22:33:38.840 回答
0

我的问题要简单得多:

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

于 2017-06-22T09:02:20.907 回答