Me doy cuenta de que la sesión y REST no van exactamente de la mano, pero ¿no es posible acceder al estado de la sesión utilizando la nueva API web? HttpContext.Current.Session
siempre es nulo.
asp.net
asp.net-web-api
marca
fuente
fuente
[SessionState(SessionStateBehavior.Required)]
en elApiController
hace el truco (o.ReadOnly
en su caso).Respuestas:
Para un proyecto MVC, realice los siguientes cambios (WebForms y Dot Net Core responden a continuación):
WebApiConfig.cs
Global.asax.cs
Esta solución tiene la ventaja adicional de que podemos obtener la URL base en JavaScript para realizar las llamadas AJAX:
_Layout.cshtml
y luego dentro de nuestros archivos / código Javascript podemos hacer nuestras llamadas webapi que pueden acceder a la sesión:
Haga lo anterior pero cambie la función WebApiConfig.Register para tomar una RouteCollection en su lugar:
Y luego llame a lo siguiente en Application_Start:
Agregue el paquete Microsoft.AspNetCore.Session NuGet y luego realice los siguientes cambios de código:
Startup.cs
Llame a los métodos AddDistributedMemoryCache y AddSession en el objeto de servicios dentro de la función ConfigureServices:
y en la función Configurar, agregue una llamada a UseSession :
SessionController.cs
Dentro de su controlador, agregue una instrucción using en la parte superior:
y luego use el objeto HttpContext.Session dentro de su código de la siguiente manera:
ahora deberías poder golpear:
y luego ir a esta URL lo sacará:
Mucha más información sobre cómo acceder a los datos de sesión dentro de dot net core aquí: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state
Lea la respuesta de Simon Weaver a continuación sobre el rendimiento. Si está accediendo a los datos de la sesión dentro de un proyecto WebApi, puede tener consecuencias muy serias en el rendimiento: he visto que ASP.NET impone un retraso de 200 ms para solicitudes concurrentes. Esto podría sumar y volverse desastroso si tiene muchas solicitudes simultáneas.
Asegúrese de bloquear recursos por usuario: un usuario autenticado no debería poder recuperar datos de su WebApi a los que no tenga acceso.
Lea el artículo de Microsoft sobre Autenticación y autorización en la API web ASP.NET: https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Lea el artículo de Microsoft sobre cómo evitar los ataques de piratería de solicitudes falsas entre sitios (En resumen, consulte el método AntiForgery.Validate): https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
fuente
Puede acceder al estado de la sesión utilizando un RouteHandler personalizado.
Encontrado aquí: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
fuente
¿Por qué evitar usar Session en WebAPI?
Rendimiento, rendimiento, rendimiento!
Hay una razón muy buena, y a menudo pasada por alto, por la que no deberías usar Session en WebAPI.
La forma en que ASP.NET funciona cuando se usa la sesión es serializar todas las solicitudes recibidas de un solo cliente . Ahora no estoy hablando de la serialización de objetos, sino de ejecutarlos en el orden recibido y esperar a que se completen antes de ejecutar el siguiente. Esto es para evitar condiciones desagradables de subproceso / carrera si dos solicitudes intentan acceder a la sesión simultáneamente.
Entonces, ¿qué significa esto para la API web? Si tiene una aplicación que ejecuta muchas solicitudes AJAX, solo UNA podrá ejecutarse a la vez. Si tiene una solicitud más lenta, bloqueará a todos los demás de ese cliente hasta que se complete. En algunas aplicaciones, esto podría conducir a un rendimiento muy notablemente lento.
Por lo tanto, probablemente debería usar un controlador MVC si necesita absolutamente algo de la sesión de los usuarios y evitar la penalización de rendimiento incesante de habilitarlo para WebApi.
Puede probar esto fácilmente por sí mismo con solo poner
Thread.Sleep(5000)
un método WebAPI y habilitar la Sesión. Ejecute 5 solicitudes y tardará un total de 25 segundos en completarse. Sin sesión, tomarán un total de poco más de 5 segundos.(Este mismo razonamiento se aplica a SignalR).
fuente
Bueno, tienes razón, REST no tiene estado. Si usa una sesión, el procesamiento pasará a estado, las solicitudes posteriores podrán usar el estado (de una sesión).
Para que una sesión se rehidrate, deberá proporcionar una clave para asociar el estado. En una aplicación asp.net normal, esa clave se proporciona mediante el uso de una cookie (sesiones de cookies) o un parámetro de URL (sesiones sin cookies).
Si necesita una sesión, olvide descansar, las sesiones son irrelevantes en los diseños basados en REST. Si necesita una sesión para la validación, use un token o autorice por direcciones IP.
fuente
Mark, si revisas el ejemplo de nerddinner MVC, la lógica es más o menos la misma.
Solo necesita recuperar la cookie y configurarla en la sesión actual.
Global.asax.cs
Tendrá que definir su clase "SampleIdentity", que puede tomar prestada del proyecto nerddinner .
fuente
Para solucionar el problema:
en Global.asax.cs
fuente
El último no funciona ahora, toma este, funcionó para mí.
en WebApiConfig.cs en App_Start
Global.asax
cuarto aquí: http://forums.asp.net/t/1773026.aspx/1
fuente
Siguiendo con la respuesta de LachlanB, si su ApiController no se encuentra dentro de un directorio particular (como / api), puede probar la solicitud usando RouteTable.Routes.GetRouteData, por ejemplo:
fuente
Tuve este mismo problema en asp.net mvc, lo solucioné colocando este método en mi controlador api base que todos mis controladores api heredan de:
Luego, en su llamada a la API que desea acceder a la sesión, simplemente haga lo siguiente:
También tengo esto en mi archivo Global.asax.cs como lo han publicado otras personas, no estoy seguro si todavía lo necesita utilizando el método anterior, pero aquí es por si acaso:
También puede crear un atributo de filtro personalizado que pueda pegar en sus llamadas de API que necesite sesión, luego puede usar la sesión en su llamada de API como lo haría normalmente a través de HttpContext.Current.Session ["SomeValue"]:
Espero que esto ayude.
fuente
Seguí el enfoque de @LachlanB y, de hecho, la sesión estaba disponible cuando la cookie de sesión estaba presente en la solicitud. La parte que falta es cómo se envía la cookie de sesión al cliente la primera vez.
Creé un HttpModule que no solo habilita la disponibilidad HttpSessionState sino que también envía la cookie al cliente cuando se crea una nueva sesión.
fuente
Una cosa debe mencionarse en la respuesta de @LachlanB.
Si omites la línea
if (IsWebApiRequest())
Todo el sitio tendrá un problema de lentitud en la carga de la página si su sitio se combina con páginas de formularios web.
fuente
Sí, la sesión no va de la mano con Rest API y también debemos evitar estas prácticas. Pero de acuerdo con los requisitos, necesitamos mantener la sesión de alguna manera tal que en cada solicitud el servidor cliente pueda intercambiar o mantener el estado o los datos. Entonces, la mejor manera de lograr esto sin romper los protocolos REST es comunicarse a través de token como JWT.
https://jwt.io/
fuente
Volviendo a lo básico, ¿por qué no mantenerlo simple y almacenar el valor de la sesión en un valor html oculto para pasar a su API?
Controlador
cshtml
Javascript
$ (documento) .ready (función () {
}
fuente