2017-04-02 1 views
1

Ich habe einige Protokollierungsdienste für meine ASP.NET Core API geschrieben.
Ich schrieb eine Middleware, das jede Aktion aufgerufen wird (Querschnitt Sorge, schien logisch) protokolliert.Verwenden von HttpContext außerhalb eines Controllers - Schlechte Praxis?

Eines der Dinge, die ich anmelden wollte, ist die IP des Benutzers (zum Beispiel). Der einzige Weg, wie ich diese Daten bekommen könnte, ist durch HttpContext.Connection.
Es funktionierte wie erwartet.

But lately I've been reading etwas mehr darüber und ich verstehe, dass der Zugriff auf HttpContext außerhalb des Controllers als eine schlechte Praxis gilt. Es macht den Code nicht testbar, da es sehr schwierig ist, nachzuahmen und zu imitieren.
Der Code ist auch nicht für andere .NET-Anwendungen portierbar und muss im Kontext der ASP.NET-Anwendung ausgeführt werden.

Also meine Frage ist - ist es wirklich so eine schlechte Praxis Httpcontext außerhalb von Controllern - innerhalb einer Middleware zum Beispiel?
Und wenn ja - was ist die Alternative?

Oder vielleicht mit HttpContext innerhalb von Komponenten, die jemals in einem ASP.NET verwendet werden (wie Top-Level-Controller oder Middleware) ist legit.

Danke.

+1

Kommt drauf an. Wenn Sie es innerhalb Ihrer Domain-Ebene (= Domain-Service) referenzieren, dann ist es definitiv eines der schlimmsten Dinge, die Sie tun können, da die Domain keine Abhängigkeiten von der Infrastruktur haben darf (db, webservice, host wie asp.net, wpf, uwp etc) .). Wenn es auf der Anwendungsebene (= Anwendungsdienst) verwendet wird, ist es in Ordnung. Der Unterschied liegt darin, dass die Anwendungsebene an die Anwendung gebunden ist und kaum oder gar nicht portierbar ist (d. H. Zugriff auf die httpcontext-Informationen, sie kann nicht mit WPF arbeiten, da es keinen httpcontext gibt) – Tseng

+0

@Tseng, Ja, dachte ich. Deshalb habe ich gefragt, ob es ok ist, es in Top-Level-Controllern und Middlewares zu verwenden - das heißt, irgendeinen Code, der im Rahmen von ASP.Net leben muss. – DotnetProg

Antwort

3

Es ist völlig in Ordnung eine Instanz einer Klasse in ASP.NET Httpcontext Kern außerhalb eines Controllers verwendet werden. Insbesondere das Schreiben einer Middleware ist nutzlos ohne eine Instanz von HttpContext, die die aktuelle Anforderung darstellt.

Der wichtigste Unterschied ist, dass Sie keine statische Accessor wie HttpContext.Current in der ASP.NET System.Web Art des Denkens verwenden sollten. In Ihrem referenzierten Blogpost wird erläutert, wie Sie dies in ASP.NET Core nachahmen können, wenn ein Großteil Ihres vorhandenen Codes davon abhängig ist. In ASP.NET Core-Bedingungen wird eine Instanz des Kontexts an Ihre Invoke-Methode Ihrer Middleware übergeben, oder Sie erhalten Zugriff auf ein IHttpContextAccessor-Objekt mithilfe der Abhängigkeitsinjektion.

Werfen Sie einen Blick auf diese Probe in der ASP.NET Core Docs. Die HttpContext wird als Parameternamen context injiziert, so dass Sie nicht auf einen statischen Zugriffsmechanismus wie HttpContext.Current angewiesen sind. Insbesondere ist dies einfacher zu testen, da Sie in Ihrem Komponententest eine eigene Instanz HttpContext erstellen und an die Methode Invoke übergeben können.

public class RequestCultureMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public RequestCultureMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public Task Invoke(HttpContext context) 
    { 
     var cultureQuery = context.Request.Query["culture"]; 
     if (!string.IsNullOrWhiteSpace(cultureQuery)) 
     { 
      var culture = new CultureInfo(cultureQuery); 

      CultureInfo.CurrentCulture = culture; 
      CultureInfo.CurrentUICulture = culture; 

     } 

     // Call the next delegate/middleware in the pipeline 
     return this._next(context); 
    } 
} 
+0

Wie gesagt, habe ich festgestellt, dass ein 'HttpContext'-Parameter an die Middleware weitergegeben wird. So konnte ich die Remote-IP-Adresse des Clients abrufen. Ich habe den subtilen Unterschied zwischen der Verwendung einer Instanz von "HttpContext" und der Verwendung der statischen "HttpContext.Current" nicht bemerkt. Also danke, dass du mich beruhigt hast. – DotnetProg

Verwandte Themen