web-dev-qa-db-ja.com

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

このアクションフィルターが内部のイベントを起動しないのはなぜですか?

69
slashp

MVCとWebAPIの両方のアセンブリを含むプロジェクトで作業している場合、ActionFilterAttributeの名前空間が何であるかを確認できますか。両方の下に2つのActionFilterAttributesがあるため、かなり混乱します。

  • WebAPI:System.Web.Http.Filters
  • MVC:System.Web.Http.Mvc
152
Troy Dai

上記の答えは間違いなく私を助けました-他の人をいくらか節約するために...ここに明確に違いがあります。

標準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);
}
33
ProVega

これに遭遇した他の人にとって、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に適用されるかどうかはわかりません。

4
Johnie Karr

完全な実装は次のとおりです。

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

私の問題はもっと簡単でした:

コントローラーが<actionPreProcessActivitiesAttribute()> _で装飾されていることを確認してください

0
bendecko

WebApiの場合、Microsoft.AspNet.WebApi.Coreをnugetからインストールする必要があります。 MVCの場合、System.Web.MVCを使用できます。

0
Baran