Ich stelle fest, dass Sitzung und REST nicht genau Hand in Hand gehen, aber ist es nicht möglich, über die neue Web-API auf den Sitzungsstatus zuzugreifen? HttpContext.Current.Session
ist immer null.
asp.net
asp.net-web-api
Kennzeichen
quelle
quelle
[SessionState(SessionStateBehavior.Required)]
auf demApiController
macht den Trick (oder.ReadOnly
wo angebracht).Antworten:
Nehmen Sie für ein MVC-Projekt die folgenden Änderungen vor (Antwort von WebForms und Dot Net Core weiter unten):
WebApiConfig.cs
Global.asax.cs
Diese Lösung hat den zusätzlichen Vorteil, dass wir die Basis-URL in Javascript für die AJAX-Aufrufe abrufen können:
_Layout.cshtml
und dann können wir in unseren Javascript-Dateien / Code unsere Webapi-Aufrufe tätigen, die auf die Sitzung zugreifen können:
Führen Sie die obigen Schritte aus, ändern Sie jedoch die Funktion WebApiConfig.Register, um stattdessen eine RouteCollection zu verwenden:
Rufen Sie dann in Application_Start Folgendes auf:
Fügen Sie das Microsoft.AspNetCore.Session NuGet-Paket hinzu und nehmen Sie die folgenden Codeänderungen vor:
Startup.cs
Rufen Sie die Methoden AddDistributedMemoryCache und AddSession für das Services-Objekt in der Funktion ConfigureServices auf:
und fügen Sie in der Funktion Konfigurieren einen Aufruf von UseSession hinzu :
SessionController.cs
Fügen Sie in Ihrem Controller oben eine using-Anweisung hinzu:
und verwenden Sie dann das HttpContext.Session-Objekt in Ihrem Code wie folgt:
Sie sollten jetzt in der Lage sein zu schlagen:
Wenn Sie dann zu dieser URL gehen, wird Folgendes angezeigt:
Weitere Informationen zum Zugriff auf Sitzungsdaten innerhalb des dot net core finden Sie hier: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state
Lesen Sie unten die Antwort von Simon Weaver zur Leistung. Wenn Sie in einem WebApi-Projekt auf Sitzungsdaten zugreifen, kann dies schwerwiegende Auswirkungen auf die Leistung haben. Ich habe gesehen, dass ASP.NET eine Verzögerung von 200 ms für gleichzeitige Anforderungen erzwingt. Dies kann sich summieren und katastrophal werden, wenn Sie viele gleichzeitige Anfragen haben.
Stellen Sie sicher, dass Sie Ressourcen pro Benutzer sperren. Ein authentifizierter Benutzer sollte keine Daten von Ihrem WebApi abrufen können, auf die er keinen Zugriff hat.
Lesen Sie den Artikel von Microsoft zur Authentifizierung und Autorisierung in der ASP.NET-Web-API - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Lesen Sie den Artikel von Microsoft zur Vermeidung von Hackangriffen auf Cross-Site Request Forgery. (Kurz gesagt, sehen Sie sich die AntiForgery.Validate-Methode an.) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
quelle
Sie können mit einem benutzerdefinierten RouteHandler auf den Sitzungsstatus zugreifen.
Hier zu finden: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
quelle
Warum sollte die Verwendung von Session in WebAPI vermieden werden?
Leistung, Leistung, Leistung!
Es gibt einen sehr guten und oft übersehenen Grund, warum Sie Session in WebAPI überhaupt nicht verwenden sollten.
ASP.NET funktioniert bei Verwendung der Sitzung, indem alle von einem einzelnen Client empfangenen Anforderungen serialisiert werden . Jetzt spreche ich nicht über die Objekt-Serialisierung, sondern über das Ausführen in der empfangenen Reihenfolge und das Warten auf den Abschluss, bevor die nächste ausgeführt wird. Dies dient dazu, unangenehme Thread- / Race-Bedingungen zu vermeiden, wenn jeweils zwei Anforderungen versuchen, gleichzeitig auf die Sitzung zuzugreifen.
Was bedeutet das für die Web-API? Wenn in einer Anwendung viele AJAX-Anforderungen ausgeführt werden, kann jeweils nur EINE ausgeführt werden. Wenn Sie eine langsamere Anforderung haben, werden alle anderen von diesem Client blockiert, bis sie abgeschlossen ist. In einigen Anwendungen kann dies zu einer merklich schleppenden Leistung führen.
Daher sollten Sie wahrscheinlich einen MVC-Controller verwenden, wenn Sie unbedingt etwas aus der Benutzersitzung benötigen, und den unnötigen Leistungsverlust vermeiden, wenn Sie ihn für WebApi aktivieren.
Sie können dies ganz einfach selbst testen, indem Sie einfach
Thread.Sleep(5000)
eine WebAPI-Methode eingeben und die Sitzung aktivieren. Führen Sie 5 Anfragen aus, und es dauert insgesamt 25 Sekunden, bis sie abgeschlossen sind. Ohne Sitzung dauern sie insgesamt etwas mehr als 5 Sekunden.(Dieselbe Argumentation gilt für SignalR).
quelle
Du hast recht, REST ist staatenlos. Wenn Sie eine Sitzung verwenden, wird die Verarbeitung statusbehaftet, nachfolgende Anforderungen können den Status (aus einer Sitzung) verwenden.
Damit eine Sitzung rehydriert werden kann, müssen Sie einen Schlüssel angeben, um den Status zuzuordnen. In einer normalen asp.net-Anwendung wird dieser Schlüssel mithilfe eines Cookies (Cookie-Sessions) oder eines URL-Parameters (Cookieless-Sessions) bereitgestellt.
Wenn Sie eine Sitzung benötigen, vergessen Sie die Ruhezeiten. Sitzungen sind in REST-basierten Designs irrelevant. Wenn Sie eine Sitzung zur Validierung benötigen, verwenden Sie ein Token oder autorisieren Sie nach IP-Adressen.
quelle
Mark, wenn Sie das nerddinner MVC-Beispiel überprüfen, ist die Logik ziemlich gleich.
Sie müssen nur das Cookie abrufen und in der aktuellen Sitzung festlegen.
Global.asax.cs
Sie müssen Ihre "SampleIdentity" -Klasse definieren, die Sie aus dem nerddinner-Projekt ausleihen können .
quelle
So beheben Sie das Problem:
in Global.asax.cs
quelle
Letzteres funktioniert jetzt nicht, nimm dieses, es hat bei mir funktioniert.
in WebApiConfig.cs bei App_Start
Global.asax
Viertens hier: http://forums.asp.net/t/1773026.aspx/1
quelle
Wenn sich Ihr ApiController nach der Antwort von LachlanB nicht in einem bestimmten Verzeichnis befindet (wie / api), können Sie die Anforderung stattdessen mit RouteTable.Routes.GetRouteData testen, zum Beispiel:
quelle
Ich hatte das gleiche Problem in asp.net mvc. Ich habe es behoben, indem ich diese Methode in meinen Basis-API-Controller eingefügt habe, von dem alle meine API-Controller erben:
Dann in Ihrem API-Aufruf, dass Sie auf die Sitzung zugreifen möchten, die Sie gerade tun:
Ich habe dies auch in meiner Global.asax.cs-Datei, wie andere Leute es gepostet haben. Ich bin mir nicht sicher, ob Sie es mit der oben beschriebenen Methode noch benötigen, aber hier ist es nur für den Fall:
Sie können auch einfach ein benutzerdefiniertes Filterattribut erstellen, mit dem Sie Ihre API-Aufrufe festhalten können, die Sie benötigen. Anschließend können Sie die Sitzung in Ihrem API-Aufruf verwenden, wie Sie es normalerweise über HttpContext.Current.Session ["SomeValue"] tun würden:
Hoffe das hilft.
quelle
Ich folgte dem @ LachlanB-Ansatz und tatsächlich war die Sitzung verfügbar, als das Sitzungscookie auf der Anfrage vorhanden war. Der fehlende Teil ist, wie das Sitzungscookie zum ersten Mal an den Client gesendet wird.
Ich habe ein HttpModule erstellt, das nicht nur die Verfügbarkeit von HttpSessionState aktiviert, sondern auch das Cookie an den Client sendet, wenn eine neue Sitzung erstellt wird.
quelle
Eines muss in der Antwort von @LachlanB erwähnt werden.
Wenn Sie die Zeile weglassen
if (IsWebApiRequest())
Auf der gesamten Website tritt ein Problem mit der Langsamkeit beim Laden von Seiten auf, wenn Ihre Website mit Webformularseiten gemischt wird.
quelle
Ja, die Sitzung geht nicht mit der Rest-API einher, und wir sollten diese Vorgehensweise auch vermeiden. Aber gemäß den Anforderungen müssen wir die Sitzung irgendwie so aufrechterhalten, dass der Client-Server bei jeder Anfrage den Status oder die Daten austauschen oder verwalten kann. Der beste Weg, dies zu erreichen, ohne die REST-Protokolle zu beschädigen, ist die Kommunikation über ein Token wie JWT.
https://jwt.io/
quelle
Zurück zu den Grundlagen, warum nicht einfach halten und den Sitzungswert in einem versteckten HTML-Wert speichern, um ihn an Ihre API zu übergeben?
Regler
cshtml
Javascript
$ (Dokument) .ready (Funktion () {
}}
quelle