webentwicklung-frage-antwort-db.com.de

Warum wird mein ASP.NET-Web-API-ActionFilterAttribute OnActionExecuting nicht ausgelöst?

Ich versuche zu implementieren, was hier gezeigt wird: http://www.piotrwalat.net/nhibernate-session-management-in-asp-net-web-api/ aber ich habe ein Problem mit meiner NhSessionManagementAttribute .

Ich habe Haltepunkte auf meiner OnActionExecuting(HttpActionContext actionContext) gesetzt, um zu sehen, ob die Funktion jemals aufgerufen wurde - es war nicht der Fall.

Ich habe meine global.asax.cs-Datei noch einmal überprüft und festgestellt, dass ich die ActionFilter tatsächlich registriert: 

GlobalConfiguration.Configuration.Filters.Add(new NhSessionManagementAttribute());

Ich habe sowohl meine Controller-Klasse selbst als auch ihre Aktionen mit dem Attribut vergebens verziert:

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

Warum feuert dieser Aktionsfilter keine der Ereignisse in ihm ab?

66
slashp

Wenn Sie in einem Projekt arbeiten, das sowohl MVC- als auch WebAPI-Assemblys enthält, können Sie überprüfen, in welchem ​​Namespace der Namespace Ihres ActionFilterAttribute enthalten ist. Es ist ziemlich verwirrend, da sich unter beiden zwei ActionFilterAttributes befinden:

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

Die Antwort oben hat mir auf jeden Fall geholfen - andere Zeit zu sparen ... hier liegt der Unterschied.

Standard-MVC-Controller verwenden:

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

OData-HTTP-Controller verwenden:

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

Für alle anderen Personen, die auf dieses Problem stoßen, wird ActionFilterAttribute nicht ausgelöst, wenn Sie YourController.YourAction von Ihrem UnitTest aus aufrufen.

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

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

    //Some Assertions
}

In der Testmethode oben werden keine ActionFilterAttributes auf YourController.YourAction aufgerufen. Jedoch; Wenn Sie YourController.YourAction über einen Browser aufrufen, wird Ihr ActionFilterAttribute aufgerufen.

Dies gilt zumindest für WebApi, aber ich weiß nicht, ob es für MVC gilt.

4
Johnie Karr

Hier ist die komplette Implementierung:

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

Mein Problem war viel einfacher:

Vergewissern Sie sich, dass Ihr Controller mit <actionPreProcessActivitiesAttribute()> _ dekoriert ist

0
bendecko

Für WebApi sollten Sie Microsoft.AspNet.WebApi.Core von Nuget installieren. Für MVC können Sie System.Web.MVC verwenden.

0
Baran