Acceso a la sesión utilizando la API web ASP.NET

268

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.Sessionsiempre es nulo.

marca
fuente
44
[SessionState(SessionStateBehavior.Required)]en el ApiControllerhace el truco (o .ReadOnlyen su caso).
Roman Starkov
@RomanStarkov No se pudo hacer que esto funcione. ¿Qué ambiente estabas usando? .NET Core?
Bondolin
@Bondolin no, esto no era Core.
Roman Starkov
@RomanStarkov MVC entonces? Tengo problemas para encontrarlo.
Bondolin
@Bondolin SessionStateAttribute y sí, MVC.
Roman Starkov

Respuestas:

336

MVC

Para un proyecto MVC, realice los siguientes cambios (WebForms y Dot Net Core responden a continuación):

WebApiConfig.cs

public static class WebApiConfig
{
    public static string UrlPrefix         { get { return "api"; } }
    public static string UrlPrefixRelative { get { return "~/api"; } }

    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    ...

    protected void Application_PostAuthorizeRequest()
    {
        if (IsWebApiRequest())
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

    private bool IsWebApiRequest()
    {
        return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative);
    }

}

Esta solución tiene la ventaja adicional de que podemos obtener la URL base en JavaScript para realizar las llamadas AJAX:

_Layout.cshtml

<body>
    @RenderBody()

    <script type="text/javascript">
        var apiBaseUrl = '@Url.Content(ProjectNameSpace.WebApiConfig.UrlPrefixRelative)';
    </script>

    @RenderSection("scripts", required: false) 

y luego dentro de nuestros archivos / código Javascript podemos hacer nuestras llamadas webapi que pueden acceder a la sesión:

$.getJSON(apiBaseUrl + '/MyApi')
   .done(function (data) {
       alert('session data received: ' + data.whatever);
   })
);

Formularios web

Haga lo anterior pero cambie la función WebApiConfig.Register para tomar una RouteCollection en su lugar:

public static void Register(RouteCollection routes)
{
    routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

Y luego llame a lo siguiente en Application_Start:

WebApiConfig.Register(RouteTable.Routes);

Dot Net Core

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:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ...

    services.AddDistributedMemoryCache();
    services.AddSession();

y en la función Configurar, agregue una llamada a UseSession :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc();

SessionController.cs

Dentro de su controlador, agregue una instrucción using en la parte superior:

using Microsoft.AspNetCore.Http;

y luego use el objeto HttpContext.Session dentro de su código de la siguiente manera:

    [HttpGet("set/{data}")]
    public IActionResult setsession(string data)
    {
        HttpContext.Session.SetString("keyname", data);
        return Ok("session data set");
    }

    [HttpGet("get")]
    public IActionResult getsessiondata()
    {
        var sessionData = HttpContext.Session.GetString("keyname");
        return Ok(sessionData);
    }

ahora deberías poder golpear:

http://localhost:1234/api/session/set/thisissomedata

y luego ir a esta URL lo sacará:

http://localhost:1234/api/session/get

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

Preocupaciones de rendimiento

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.


Preocupaciones de seguridad

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

Rocklan
fuente
77
Perfecto. Simple y funciona. Para no MVC, simplemente agregue Application_PostAuthorizeRequest () a Global.ascx.cs.
mhenry1384
1
Gracias @JCallico, supongo que la mayoría de las personas llegan primero a la página ASP.NET que crea la sesión.
Rocklan
3
Necesitaba modificar IsWebApiRequest () para que también devuelva verdadero donde la ruta comienza con WebApiConfig.UrlPrefix, así como WebApiConfig.UrlPrefixRelative. Aparte de eso, funciona como se esperaba.
gb2d
77
Una cosa para mencionar con respecto a esta solución. al configurar SessionStateBehavior como Requerido, está bloqueando el webapi, porque todas sus solicitudes se ejecutarán sincronizadas debido a bloqueos en el objeto de la sesión. En su lugar, podría ejecutarlo como SessionStateBehavior.Readonly. De esta manera, no creará bloqueos en el objeto de sesión.
Michael Kire Hansen
2
Tenga cuidado al configurar el comportamiento del estado de la sesión en "Obligatorio". Las solicitudes con permisos de escritura bloquearán la sesión y evitarán que se generen múltiples HttpApplications por cliente. Debe establecer el estado de la sesión en un nivel apropiado para cada ruta. Consulte mi respuesta aquí: stackoverflow.com/a/34727708/1412787
Axel Wilczek
66

Puede acceder al estado de la sesión utilizando un RouteHandler personalizado.

// In global.asax
public class MvcApp : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var route = routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        route.RouteHandler = new MyHttpControllerRouteHandler();
    }
}

// Create two new classes
public class MyHttpControllerHandler
    : HttpControllerHandler, IRequiresSessionState
{
    public MyHttpControllerHandler(RouteData routeData) : base(routeData)
    { }
}
public class MyHttpControllerRouteHandler : HttpControllerRouteHandler
{
    protected override IHttpHandler GetHttpHandler(
        RequestContext requestContext)
    {
        return new MyHttpControllerHandler(requestContext.RouteData);
    }
}

// Now Session is visible in your Web API
public class ValuesController : ApiController
{
    public string Get(string input)
    {
        var session = HttpContext.Current.Session;
        if (session != null)
        {
            if (session["Time"] == null)
                session["Time"] = DateTime.Now;
            return "Session Time: " + session["Time"] + input;
        }
        return "Session is not availabe" + input;
    }
}

Encontrado aquí: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html

warrickh
fuente
14
Actualización: si las funciones de su API leen de la sesión y no modifican la sesión, puede ser una buena idea usar IReadOnlySessionState en lugar de IRequiresSessionState. Esto garantiza que la sesión no esté bloqueada durante el procesamiento de la función API.
warrickh
66
no funciona para mí en MVC 4 - route.RouteHandler ni siquiera es una propiedad para mí. @LachlanB parece tener lo que funcionó para mí.
bkwdesign
3
Gracias @bkwdesign por señalar la solución MVC. Esta respuesta se refiere solo a la API web.
warrickh
2
Esto no parece admitir atributos de ruta. Pensamientos?
Tim S
Como señaló bkwdesign, esto ya no es compatible. Sin embargo, hay una manera de definir el comportamiento del estado de sesión por ruta usando DataTokens: stackoverflow.com/a/34727708/1412787
Axel Wilczek
46

¿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.

Solicitudes concurrentes y estado de sesión

El acceso al estado de sesión ASP.NET es exclusivo por sesión, lo que significa que si dos usuarios diferentes realizan solicitudes concurrentes, el acceso a cada sesión por separado se otorga simultáneamente. Sin embargo, si se realizan dos solicitudes simultáneas para la misma sesión (utilizando el mismo valor de SessionID), la primera solicitud obtiene acceso exclusivo a la información de la sesión. La segunda solicitud se ejecuta solo después de que la primera solicitud haya finalizado.(La segunda sesión también puede obtener acceso si el bloqueo exclusivo de la información se libera porque la primera solicitud excede el tiempo de espera de bloqueo). Si el valor EnableSessionState en la directiva @ Page se establece en ReadOnly, una solicitud de solo lectura la información de la sesión no produce un bloqueo exclusivo en los datos de la sesión. Sin embargo, es posible que las solicitudes de solo lectura para los datos de la sesión aún tengan que esperar un bloqueo establecido por una solicitud de lectura y escritura para que se borren los datos de la sesión.

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).

Simon_Weaver
fuente
18
Puede solucionar esto utilizando [SessionState (SessionStateBehavior.ReadOnly)] si su método solo lee de la sesión.
Rocklan
21

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.

Nickz
fuente
10
No estoy seguro de esto. En los ejemplos de Microsoft, muestran el uso del atributo Autorizar. Lo he intentado y funciona con la autenticación basada en formularios. La API web conoce el estado de autenticación que se pasa en la cookie de autenticación predeterminada.
Mark
44
Aquí está la muestra a la que me refiero, code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7 . Utiliza la nueva API web basada en REST que implementa la autenticación de formularios.
Mark
44
He usado el atributo [Autorizar] con éxito sin necesidad del estado de la sesión. Acabo de escribir un controlador de mensajes de autenticación para establecer la identidad.
Antony Scott
57
Te marcó porque no ofreciste una respuesta a su problema, y ​​más aún, la Web Api es un marco asincrónico que funciona muy bien con una aplicación web pesada ajax. Nadie dijo que tenía que respetar a todos los inquilinos de diseño RESTful para obtener beneficios del uso del marco de la API web.
Brian Ogden
3
@Marcas. Es correcto informar que la API web no debe conocer el estado de la sesión. La respuesta negativa sigue siendo una respuesta. Hasta el voto.
Antoine Meltzheim
20

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

public override void Init()
{
    this.AuthenticateRequest += new EventHandler(WebApiApplication_AuthenticateRequest);
    base.Init();
}

void WebApiApplication_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

    SampleIdentity id = new SampleIdentity(ticket);
    GenericPrincipal prin = new GenericPrincipal(id, null); 

    HttpContext.Current.User = prin;
}

enter code here

Tendrá que definir su clase "SampleIdentity", que puede tomar prestada del proyecto nerddinner .

JSancho
fuente
La clase de identidad está en NerdDinner_2.0 \ NerdDinner \ Models \ NerdIdentity.cs.
mhenry1384
Esto no funciona para mí (en .NET 4). Nunca tengo esa galleta. ¿Funciona solo si tiene la autenticación de formularios activada?
mhenry1384
la cookie se genera después de que se autentica a través del formulario de inicio de sesión. También puede personalizar cómo / cuándo se crea, consulte stackoverflow.com/questions/7217105 Pero aún necesita que el usuario se autentique efectivamente en el servidor web
JSancho
La pregunta pide HttpContext.Current.Session y esta respuesta no explica claramente lo que hay que hacer. Ver la respuesta de @LachlanB.
JCallico
14

Para solucionar el problema:

protected void Application_PostAuthorizeRequest()
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}

en Global.asax.cs

Suresh Muttagi
fuente
44
¡Advertencia! Esto habilitará la sesión para TODAS las solicitudes. Esto realmente puede afectar el rendimiento si su aplicación está utilizando recursos integrados.
cgatian
@cgatian ninguna solución alternativa fija ?
Kiquenet
Creo que el mejor enfoque es lo que sugiere @Treyphor. No lo habilite para todas las solicitudes. Solo rutas que tengan "/ api" o algo en la URL. Además, si es posible, configure el estado de la sesión para que solo se lea en sus controladores API.
cgatian
10

El último no funciona ahora, toma este, funcionó para mí.

en WebApiConfig.cs en App_Start

    public static string _WebApiExecutionPath = "api";

    public static void Register(HttpConfiguration config)
    {
        var basicRouteTemplate = string.Format("{0}/{1}", _WebApiExecutionPath, "{controller}");

        // Controller Only
        // To handle routes like `/api/VTRouting`
        config.Routes.MapHttpRoute(
            name: "ControllerOnly",
            routeTemplate: basicRouteTemplate//"{0}/{controller}"
        );

        // Controller with ID
        // To handle routes like `/api/VTRouting/1`
        config.Routes.MapHttpRoute(
            name: "ControllerAndId",
            routeTemplate: string.Format ("{0}/{1}", basicRouteTemplate, "{id}"),
            defaults: null,
            constraints: new { id = @"^\d+$" } // Only integers 
        );

Global.asax

protected void Application_PostAuthorizeRequest()
{
  if (IsWebApiRequest())
  {
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
  }
}

private static bool IsWebApiRequest()
{
  return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(_WebApiExecutionPath);
}

cuarto aquí: http://forums.asp.net/t/1773026.aspx/1

Cruiser KID
fuente
Esta es la solución más simple, pero tiene algunos errores en el código, por lo que en realidad no funciona. He publicado otra solución basada en esta, no dudes en editar la tuya para que coincida con la mía.
Rocklan
La corrección leve en la línea _WebApiExecutionPath necesita leer la cadena estática pública _WebApiExecutionPath = "~ / api";
stephen ebichondo
8

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:

protected void Application_PostAuthorizeRequest()
    {
        // WebApi SessionState
        var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
        if (routeData != null && routeData.RouteHandler is HttpControllerRouteHandler)
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
    }
Stumblor
fuente
8

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:

    /// <summary>
    /// Get the session from HttpContext.Current, if that is null try to get it from the Request properties.
    /// </summary>
    /// <returns></returns>
    protected HttpContextWrapper GetHttpContextWrapper()
    {
      HttpContextWrapper httpContextWrapper = null;
      if (HttpContext.Current != null)
      {
        httpContextWrapper = new HttpContextWrapper(HttpContext.Current);
      }
      else if (Request.Properties.ContainsKey("MS_HttpContext"))
      {
        httpContextWrapper = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
      }
      return httpContextWrapper;
    }

Luego, en su llamada a la API que desea acceder a la sesión, simplemente haga lo siguiente:

HttpContextWrapper httpContextWrapper = GetHttpContextWrapper();
var someVariableFromSession = httpContextWrapper.Session["SomeSessionValue"];

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:

/// <summary>
/// The following method makes Session available.
/// </summary>
protected void Application_PostAuthorizeRequest()
{
  if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/api"))
  {
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
  }
}

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"]:

  /// <summary>
  /// Filter that gets session context from request if HttpContext.Current is null.
  /// </summary>
  public class RequireSessionAttribute : ActionFilterAttribute
  {
    /// <summary>
    /// Runs before action
    /// </summary>
    /// <param name="actionContext"></param>
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
      if (HttpContext.Current == null)
      {
        if (actionContext.Request.Properties.ContainsKey("MS_HttpContext"))
        {
          HttpContext.Current = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).ApplicationInstance.Context;
        }
      }
    }
  }

Espero que esto ayude.

Treyphor
fuente
6

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.

public class WebApiSessionModule : IHttpModule
{
    private static readonly string SessionStateCookieName = "ASP.NET_SessionId";

    public void Init(HttpApplication context)
    {
        context.PostAuthorizeRequest += this.OnPostAuthorizeRequest;
        context.PostRequestHandlerExecute += this.PostRequestHandlerExecute;
    }

    public void Dispose()
    {
    }

    protected virtual void OnPostAuthorizeRequest(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        if (this.IsWebApiRequest(context))
        {
            context.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

    protected virtual void PostRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        if (this.IsWebApiRequest(context))
        {
            this.AddSessionCookieToResponseIfNeeded(context);
        }
    }

    protected virtual void AddSessionCookieToResponseIfNeeded(HttpContext context)
    {
        HttpSessionState session = context.Session;

        if (session == null)
        {
            // session not available
            return;
        }

        if (!session.IsNewSession)
        {
            // it's safe to assume that the cookie was
            // received as part of the request so there is
            // no need to set it
            return;
        }

        string cookieName = GetSessionCookieName();
        HttpCookie cookie = context.Response.Cookies[cookieName];
        if (cookie == null || cookie.Value != session.SessionID)
        {
            context.Response.Cookies.Remove(cookieName);
            context.Response.Cookies.Add(new HttpCookie(cookieName, session.SessionID));
        }
    }

    protected virtual string GetSessionCookieName()
    {
        var sessionStateSection = (SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");

        return sessionStateSection != null && !string.IsNullOrWhiteSpace(sessionStateSection.CookieName) ? sessionStateSection.CookieName : SessionStateCookieName;
    }

    protected virtual bool IsWebApiRequest(HttpContext context)
    {
        string requestPath = context.Request.AppRelativeCurrentExecutionFilePath;

        if (requestPath == null)
        {
            return false;
        }

        return requestPath.StartsWith(WebApiConfig.UrlPrefixRelative, StringComparison.InvariantCultureIgnoreCase);
    }
}
JCallico
fuente
Esto funciona muy bien. Esto mantiene la sesión igual entre las solicitudes, siempre que no se haya agotado el tiempo de espera. No estoy seguro de si voy a usarlo en producción todavía hasta que encuentre una buena manera de cambiar el estado de sesión entre requerido y leer solo para detener el bloqueo de solicitudes, pero esto me ha dado la ruta de inicio que deseo. ¡Gracias!
Derreck Dean
3

Una cosa debe mencionarse en la respuesta de @LachlanB.

protected void Application_PostAuthorizeRequest()
    {
        if (IsWebApiRequest())
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

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.

maxisam
fuente
0

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/

Sulabh Singla
fuente
-4

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

public ActionResult Index()
        {

            Session["Blah"] = 609;

            YourObject yourObject = new YourObject();
            yourObject.SessionValue = int.Parse(Session["Blah"].ToString());

            return View(yourObject);
        }

cshtml

@model YourObject

@{
    var sessionValue = Model.SessionValue;
}

<input type="hidden" value="@sessionValue" id="hBlah" />

Javascript

$ (documento) .ready (función () {

    var sessionValue = $('#hBlah').val();

    alert(sessionValue);

    /* Now call your API with the session variable */}

}

Andy A.
fuente
1
¿Qué sucede si la aplicación usa MVC y WebAPI? Además, es más razonable almacenar algunas cosas en el lado del servidor, por ejemplo, tokens de seguridad de Sharepoint. En lugar de implementar un contenedor especial para el almacenamiento de tokens como el contenedor de blobs azules, a veces es razonable reutilizar Session para este tipo de datos. El contexto de seguridad de Sharepoint, tal como se implementó en la plantilla de la aplicación, utiliza la sesión para almacenar estos contextos de seguridad, y solo se transfieren pequeños datos (etiqueta de sesión) en lugar de unos pocos kilobytes de datos. Sería increíble si este contexto fuera más pequeño ...
Konstantin Isaev