Acessando a sessão usando a API da Web do ASP.NET


268

Sei que a sessão e o REST não andam exatamente de mãos dadas, mas não é possível acessar o estado da sessão usando a nova API da Web? HttpContext.Current.Sessioné sempre nulo.


4
[SessionState(SessionStateBehavior.Required)]no ApiControllerfaz o truque (ou .ReadOnlyonde apropriado).
Roman Starkov 26/03

@RomanStarkov Não foi possível fazer isso funcionar. Que ambiente você estava usando? .NET Core?
Bondolin 27/02/19

@ Bondolin não, este não era o Core.
Roman Starkov

@RomanStarkov MVC então? Estou tendo problemas para encontrá-lo.
Bondolin 5/03/19

@Bondolin SessionStateAttribute e sim, MVC.
Roman Starkov

Respostas:


336

MVC

Para um projeto MVC, faça as seguintes alterações (WebForms e Dot Net Core respondem abaixo):

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 solução tem o bônus adicional de que podemos buscar o URL base em javascript para fazer as chamadas AJAX:

_Layout.cshtml

<body>
    @RenderBody()

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

    @RenderSection("scripts", required: false) 

e, em nossos arquivos / códigos Javascript, podemos fazer nossas chamadas de webapi que podem acessar a sessão:

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

WebForms

Faça o acima, mas altere a função WebApiConfig.Register para obter um RouteCollection:

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

E, em seguida, chame o seguinte em Application_Start:

WebApiConfig.Register(RouteTable.Routes);

Dot Net Core

Adicione o pacote Microsoft.AspNetCore.Session NuGet e faça as seguintes alterações de código:

Startup.cs

Chame os AddDistributedMemoryCache e AddSession métodos nos serviços objeto dentro da função ConfigureServices:

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

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

e na função Configurar, adicione uma chamada ao UseSession :

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

SessionController.cs

No seu controlador, adicione uma instrução using na parte superior:

using Microsoft.AspNetCore.Http;

e use o objeto HttpContext.Session dentro do seu código da seguinte maneira:

    [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);
    }

agora você deve conseguir:

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

e, em seguida, acessar este URL o retirará:

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

Muito mais informações sobre o acesso aos dados da sessão no dot net core aqui: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

Preocupações com o desempenho

Leia a resposta de Simon Weaver abaixo sobre desempenho. Se você estiver acessando dados da sessão dentro de um projeto WebApi, isso poderá ter conseqüências muito sérias no desempenho - eu já vi o ASP.NET impor um atraso de 200ms para solicitações simultâneas. Isso pode aumentar e se tornar desastroso se você tiver muitas solicitações simultâneas.


Preocupações com segurança

Verifique se você está bloqueando recursos por usuário - um usuário autenticado não poderá recuperar dados de seus WebApi aos quais não tem acesso.

Leia o artigo da Microsoft sobre autenticação e autorização na API da Web do ASP.NET - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Leia o artigo da Microsoft sobre como evitar ataques de hackers de solicitação de falsificação entre sites. (Em resumo, confira o método AntiForgery.Validate) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks


7
Perfeito. Simples e funciona. Para não-MVC, basta adicionar Application_PostAuthorizeRequest () ao Global.ascx.cs.
precisa saber é o seguinte

1
Obrigado @JCallico, acho que a maioria das pessoas acessa a página ASP.NET primeiro, que cria a sessão.
Rocklan

3
Eu precisava modificar IsWebApiRequest () para também retornar true onde o caminho começa com WebApiConfig.UrlPrefix, bem como WebApiConfig.UrlPrefixRelative. Fora isso, funciona como esperado.
Gb2d

7
Uma coisa a mencionar sobre essa correção. ao definir o SessionStateBehavior como Necessário, você está afunilando a webapi, porque todas as suas solicitações serão executadas sincronizadas devido a bloqueios no objeto da sessão. Em vez disso, você poderia executá-lo como SessionStateBehavior.Readonly. Dessa forma, ele não criará bloqueios no objeto da sessão.
Michael Kire Hansen

2
Tenha cuidado ao definir o comportamento do estado da sessão como "Necessário". Pedidos com permissões de gravação bloquearão a sessão e impedirão que vários HttpApplications sejam gerados por cliente. Você deve definir o estado da sessão para um nível apropriado para cada rota. Consulte a minha resposta aqui: stackoverflow.com/a/34727708/1412787 #
Axel Wilczek

66

Você pode acessar o estado da sessão usando um 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 aqui: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html


14
Atualização: se as funções da API leem da sessão e não modificam a sessão, pode ser uma boa ideia usar IReadOnlySessionState em vez de IRequiresSessionState. Isso garante que a sessão não seja bloqueada durante o processamento da função API.
warrickh

6
não está funcionando para mim no MVC 4 - route.RouteHandler nem sequer é uma propriedade para mim. @LachlanB parece ter o que funcionou para mim.
Bkwdesign 26/08

3
Obrigado @bkwdesign por apontar a solução MVC. Esta resposta está relacionada apenas à API da Web.
warrickh

2
Isso não parece suportar os atributos de rota. Pensamentos?
Tim S

Como o bkwdesign apontou, isso não é mais suportado. No entanto, existe uma maneira de definir o comportamento do estado da sessão por rota usando DataTokens: stackoverflow.com/a/34727708/1412787
Axel Wilczek

46

Por que evitar o uso da sessão na WebAPI?

Desempenho, desempenho, desempenho!

Há uma razão muito boa e muitas vezes esquecida pela qual você não deve usar a Sessão na WebAPI.

A maneira como o ASP.NET funciona quando a Sessão está em uso é serializar todas as solicitações recebidas de um único cliente . Agora não estou falando sobre serialização de objetos - mas executando-os na ordem recebida e aguardando a conclusão de cada um antes de executar o próximo. Isso evita condições desagradáveis ​​de thread / corrida se duas solicitações tentarem acessar a sessão simultaneamente.

Solicitações simultâneas e estado da sessão

O acesso ao estado da sessão do ASP.NET é exclusivo por sessão, o que significa que, se dois usuários diferentes fizerem solicitações simultâneas, o acesso a cada sessão separada será concedido simultaneamente. No entanto, se duas solicitações simultâneas forem feitas para a mesma sessão (usando o mesmo valor de SessionID), a primeira solicitação obterá acesso exclusivo às informações da sessão. A segunda solicitação é executada somente após a conclusão da primeira solicitação.(A segunda sessão também pode obter acesso se o bloqueio exclusivo das informações for liberado porque a primeira solicitação exceder o tempo limite do bloqueio). Se o valor EnableSessionState na diretiva @ Page estiver definido como ReadOnly, uma solicitação para o somente leitura as informações da sessão não resultam em um bloqueio exclusivo nos dados da sessão. No entanto, as solicitações somente leitura para dados da sessão ainda precisam aguardar um bloqueio definido por uma solicitação de leitura e gravação para que os dados da sessão sejam limpos.

Então, o que isso significa para a API da Web? Se você tiver um aplicativo executando muitas solicitações AJAX, apenas um poderá executar por vez. Se você tiver uma solicitação mais lenta, ela bloqueará todas as outras desse cliente até sua conclusão. Em algumas aplicações, isso pode levar a um desempenho notavelmente lento.

Portanto, você provavelmente deve usar um controlador MVC se precisar absolutamente de algo da sessão de usuários e evitar a penalidade desnecessária de desempenho ao habilitá-lo para o WebApi.

Você pode facilmente testar isso sozinho Thread.Sleep(5000)inserindo um método WebAPI e habilitando a Session. Execute 5 solicitações e elas levarão um total de 25 segundos para serem concluídas. Sem a sessão, eles levarão um total de pouco mais de 5 segundos.

(Esse mesmo raciocínio se aplica ao SignalR).


18
Você pode contornar isso usando [SessionState (SessionStateBehavior.ReadOnly)] se o seu método apenas ler da sessão.
Rocklan 15/07/2015

21

Bem, você está certo, o REST é sem estado. Se você usar uma sessão, o processamento se tornará estável, as solicitações subsequentes poderão usar o estado (de uma sessão).

Para que uma sessão seja reidratada, você precisará fornecer uma chave para associar o estado. Em um aplicativo asp.net normal, essa chave é fornecida usando um parâmetro cookie (sessões de cookie) ou url (sessões sem cookies).

Se você precisar de uma sessão, esqueça o resto, as sessões são irrelevantes nos designs baseados em REST. Se você precisar de uma sessão para validação, use um token ou autorize por endereços IP.


10
Eu não tenho certeza sobre isso. Nos exemplos da Microsoft, eles mostram o uso do atributo Autorizar. Eu tentei isso e funciona com autenticação baseada em formulários. A API da Web está ciente do estado de autenticação que está sendo passado no cookie de autenticação padrão.
Mark

4
Aqui está o exemplo ao qual estou me referindo, code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7 . Ele usa a nova API da Web baseada em REST implementa a autenticação de formulários.
Mark

4
Eu usei o atributo [Autorizar] com sucesso sem precisar do estado da sessão. Acabei de escrever um manipulador de mensagens de autenticação para definir a identidade.
Antony Scott

57
Marcou você como não tendo respondido ao problema e, mais ainda, a API da Web é uma estrutura assíncrona que funciona muito bem com um aplicativo Web pesado do Ajax. Ninguém disse que era necessário respeitar todos os inquilinos do design RESTful para obter benefícios ao usar a estrutura da API da Web.
Brian Ogden

3
@MarkS. tem razão em informar que a API da Web não deve estar ciente do estado da sessão. A resposta negativa ainda permanece uma resposta. Up vote.
Antoine Meltzheim

20

Marque, se você verificar o exemplo do nerddinner MVC, a lógica é praticamente a mesma.

Você só precisa recuperar o cookie e configurá-lo na sessão atual.

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

Você terá que definir sua classe "SampleIdentity", que pode ser emprestada do projeto nerddinner .


A classe de identidade está em NerdDinner_2.0 \ NerdDinner \ Models \ NerdIdentity.cs.
precisa saber é o seguinte

Isso não funciona para mim (no .NET 4). Eu nunca tenho esse biscoito. Funciona apenas se você tiver o FormsAuthentication ativado?
precisa saber é o seguinte

o cookie é realmente gerado depois que você se autentica através do formulário de login. Você também pode personalizar a forma como / quando ele é criado, consulte stackoverflow.com/questions/7217105 Mas você ainda precisa que o usuário efetivamente autenticar contra o servidor web
JSancho

A pergunta pede HttpContext.Current.Session e esta resposta não explica claramente o que precisa ser feito. Consulte a resposta @LachlanB.
JCallico 29/04

14

Para corrigir o problema:

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

no Global.asax.cs


4
Aviso! Isso permitirá a sessão para TODAS as solicitações. Isso pode prejudicar o desempenho se o aplicativo estiver usando recursos incorporados.
precisa saber é

@cgatian alguma solução alternativa foi corrigida ?
Kiquenet

Acho que a melhor abordagem é o que o @Treyphor sugere. Não ative para todas as solicitações. Apenas rotas com "/ api" ou algo no URL. Além disso, se possível, defina o estado da sessão como somente leitura para seus controladores de API.
Cgatian

10

O último não está funcionando agora, pegue este, funcionou para mim.

no WebApiConfig.cs em 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);
}

quarto aqui: http://forums.asp.net/t/1773026.aspx/1


Essa é a solução mais simples, mas com alguns erros no código, para que não funcione de verdade. Publiquei outra solução com base nesta, fique à vontade para editar a sua para corresponder à minha.
Rocklan

Uma pequena correção na linha _WebApiExecutionPath precisa ler a sequência estática pública _WebApiExecutionPath = "~ / api";
stephen ebichondo 16/05

8

Seguindo a resposta de LachlanB, se o seu ApiController não estiver em um diretório específico (como / api), você poderá testar a solicitação usando RouteTable.Routes.GetRouteData, por exemplo:

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);
    }

8

Eu tive esse mesmo problema no asp.net mvc, eu o corrigi colocando esse método no meu controlador api básico que todos os meus controladores api herdam:

    /// <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;
    }

Em sua chamada de API, você deseja acessar a sessão que acabou de fazer:

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

Eu também tenho isso no meu arquivo Global.asax.cs, como outras pessoas postaram, não tenho certeza se você ainda precisa dele usando o método acima, mas aqui está o caso:

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

Você também pode criar um atributo de filtro personalizado que possa ser usado nas chamadas da API que você precisa, e poderá usar a sessão na sua chamada da API como faria normalmente via 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 isto ajude.


6

Eu segui a abordagem @LachlanB e, de fato, a sessão estava disponível quando o cookie da sessão estava presente na solicitação. A parte que falta é como o cookie de sessão é enviado ao cliente pela primeira vez?

Criei um HttpModule que não apenas habilita a disponibilidade do HttpSessionState, mas também envia o cookie ao cliente quando uma nova sessão é criada.

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);
    }
}

Isso funciona muito bem. Isso mantém a sessão igual entre solicitações, desde que não tenha atingido o tempo limite. Ainda não tenho certeza se vou usá-lo no prod até descobrir uma boa maneira de alternar o estado da sessão entre obrigatório e ler apenas para parar o bloqueio de solicitações, mas isso me deu o caminho inicial que desejo. Obrigado!
Derreck Dean

3

uma coisa precisa ser mencionada na resposta de @LachlanB.

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

Se você omitir a linha if (IsWebApiRequest())

O site inteiro terá um problema de lentidão no carregamento da página se o site for misturado com páginas de formulário da web.


0

Sim, a sessão não anda de mãos dadas com a API Rest e também devemos evitar essas práticas. Mas, de acordo com os requisitos, precisamos manter a sessão de alguma forma, de modo que, em cada solicitação, o servidor cliente possa trocar ou manter estado ou dados. Portanto, a melhor maneira de conseguir isso sem quebrar os protocolos REST é se comunicar através de token como JWT.

https://jwt.io/


-4

Voltando ao básico, por que não mantê-lo simples e armazenar o valor da Sessão em um valor html oculto para passar para sua 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

$ (document) .ready (function () {

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

    alert(sessionValue);

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

}


1
Por que o aplicativo usa MVC e WebAPI? Além disso, é mais razoável guardar algumas coisas no lado do servidor, por exemplo, tokens de segurança do Sharepoint. Em vez de implementar um wrapper especial para armazenamento de tokens como o contêiner de blobs do azure, às vezes é razoável reutilizar a sessão para esse tipo de dados. O contexto de segurança do Sharepoint, conforme implementado no modelo de aplicativo, usa a sessão para armazenar esses contextos de segurança e apenas pequenos pedaços de dados sendo transferidos (tag de sessão) em vez de poucos kilobytes de dados. Seria fantástico se estes contexto seria menor ...
Konstantin Isaev
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.