Freitag, April 10, 2020

System.Web.Http.Filter.ActionFilterAttribute müssen im gleichen Projekt als controller?

Habe ich ein System.Web.Http.ApiController-abgeleitet controller:

[LoggingFilterApi]
public class BaseController : ApiController
{
     public IHttpActionResult Ads();
}

den filter wie folgt definiert:

using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace pecom.Common.Filters
{
    public class LoggingFilterApiAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext ctx)
        {
            var msg = ctx.ActionDescriptor.ControllerDescriptor.ControllerType.Name + "." + ctx.ActionDescriptor.ActionName +
                "(" + ctx.Request.RequestUri.ToString();

            ILog logger = LogManager.GetLogger(ctx.ActionDescriptor.ControllerDescriptor.ControllerType);
            logger.Info(msg);
            base.OnActionExecuting(ctx);
        }
    }
}

Wenn LoggingFilterApiAttribute.cs ist Teil der controller ist .csproj, OnActionExecuting aufgerufen, wie erwartet. Allerdings, wenn LoggingFilterApiAttribute.cs umgezogen ist und eine andere .csproj (zur Erleichterung der Wiederverwendung von code), OnActionExecuting ist nicht aufgerufen, wie erwartet. Komisch.

Jemand gesehen? Zur Zeit bin ich duplizieren-Filter über unsere Projekte, die suboptimal ist. Dies ist mit ASP.NET MVC 5.2.

Cheers, Pete

  • Es heißt, es funktioniert einfach nicht melden. Wie wollen Sie initialisieren Log4Net?
  • von der Verwendung von breakpoints kann ich Ihnen sagen, es wird nicht aufgerufen (wenn LoggingFilterApiAttribute.cs ist in einer anderen proj). Und so nebenbei, Filter ableiten von System.Web.Mvc.ActionFilterAttribute nicht zeigen dieses seltsame Verhalten.
  • Ich sehe das auch. Ich habe eine einfache Web-API-Projekt, erstellt einen filter drin, die nichts tut, aber schreiben Sie die Spur in beide OnExecuting und OnExecuted, Hinzugefügt, um die Globale filter-Sammlung, die es lief, und es funktionierte gut. Bewegt den filter in einem separaten assembly Hinzugefügt, entsprechenden Referenzen und verkabelten alles sichern, und es läuft nicht mehr.
  • Ich habe nur geworfen, zusammen einen test-API-Projekt und eine Bibliothek-Klasse, und das funktioniert mit dem code in den OP. MVC 5.2 .Net 4.5, die ich verwendet habe Filter in verschiedenen Projekten, viele, viele Male, es gibt keinen Grund, warum es nicht funktionieren sollte. Verwenden Sie IIS Express oder IIS? Ist das API-Projekt und die Bibliothek-Klasse auf das gleiche framework-version?
  • System.Web.Mvc-v5.2.2.0. Beide Projekte sind .NET Framework 4.5. Ich habe versucht, in der IIS-Express über F5-debug (sehen, Verhalten im debugger und in der VS-Ausgabe von Trace-Fenster.Debug) und auch in der lokalen IIS und beobachten trace-Ausgabe über dbgview. Ich habe versucht, durch das hinzufügen der filter auf die Globale Filter, als auch nur, indem es einen API-Methode über ein Attribut. Das Ergebnis ist immer das gleiche: Wenn ich einen filter definiert, die in das web-Projekt ist, läuft es, aber f ich verwenden die gleiche Implementierung definiert, die in einer separaten Bibliothek, tut es nicht. Es gibt keine Ausnahmen, Warnungen etc. überall.
  • Haben Sie versucht, die Schaffung von 2 neuen test-Projekte (web & Bibliothek) komplett zu trennen, um dies mit nur das absolute minimum, um zu sehen, wenn Sie können, führen Sie die filter in einem anderen Projekt dann? Stripping Dinge wieder, ist ein Weg, wie ich finde Lösungen für Probleme
  • Ja, siehe Kommentar oben. Ich habe eine out-of-the-box, unveränderte Web-API-Projekt mit keine Authentifizierung und eine Bibliothek-Klasse. Ein filter in der Web-API-Projekt genannt, aber eine in der Klasse die Bibliothek nicht.

InformationsquelleAutor sming | 2015-03-27

2 Kommentare

  1. 5

    Dann haben Sie wahrscheinlich eine Diskrepanz in der Web-Api-2-Versionen. Egal, welche version von MVC-der controller ist eine Web-Api, so haben Sie, um die Aufmerksamkeit auf Web-Api im Zusammenhang Baugruppen.

    Ich bin mir ziemlich sicher, dass, wenn Sie überprüfen Sie die version der System.Web.Http jeweils im MVC-Projekt und die Bibliothek-Klasse, Sie werden anders sein, und daher die Entdeckung Mechanismus nicht finden können Sie Ihre benutzerdefinierten filter. Nur das problem beheben, indem Sie Sie zu passen und es sollte funktionieren.

    Einen einfachen Weg, das zu beheben, der zum verweisen auf die neuesten Web-Api-2-Paket (Microsoft.AspNet.WebApi.Core) in die Bibliothek-Klasse, und upgrade das gleiche Paket in der MVC-Projekt zu machen, übereinstimmen (oder von messing mit der Montage leitet, wenn Sie gerne so). Wenn, zum Beispiel, die Sie gerade kopiert den code in die Klasse library, und dann verwendet, so etwas wie Resharper zum auflösen der Verweise, könnte es wahrscheinlich aufgenommen hast, version 4.x System.Web.Http von GAC, statt der version 5.x, dass Sie hier benötigen.

    Ich habe versucht, was Sie getan, und es reproduziert Ihre gleiche Problem, und dieses Verfahren gelöst.

    • Toller Fund, genau das war das problem. Danke!
    • schön gespielt Wespe!
  2. 1

    Schaffte ich es in ein paar Schritten :

    1. Erstellen einer MVC-Anwendung
    2. Eine leere Klasse erstellen Bibliothek
    3. fügen Sie das MVC-framework-Klassenbibliothek mit nuget
    4. hinzufügen Verweis auf System.Web-to-Klasse Bibliothek Projekt
    5. Kopieren Sie den code in eine neue Klasse von der Klasse Bibliothek
    6. Code entfernen damit den logger für Testzwecke
    7. Ersetzen HttpActionContext ctx von ActionExecutingContext
      filterContext
    8. Ersetzen ctx.Anfrage.RequestUri.ToString() durch
      filterContext.HttpContext.Anfrage.Url
    9. Verweis auf die Klasse-Bibliothek-Projekt
    10. Fügen Sie den filter auf der home controller

    Job gemacht

Kostenlose Online-Tests