Accessing Session Using ASP.NET Web API

前端 未结 13 1164
谎友^
谎友^ 2020-11-22 04:32

I realize session and REST don\'t exactly go hand in hand but is it not possible to access session state using the new Web API? HttpContext.Current.Session is a

13条回答
  •  死守一世寂寞
    2020-11-22 05:30

    MVC

    For an MVC project make the following changes (WebForms and Dot Net Core answer down below):

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

    This solution has the added bonus that we can fetch the base URL in javascript for making the AJAX calls:

    _Layout.cshtml

    
        @RenderBody()
    
        
    
        @RenderSection("scripts", required: false) 
    

    and then within our Javascript files/code we can make our webapi calls that can access the session:

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

    WebForms

    Do the above but change the WebApiConfig.Register function to take a RouteCollection instead:

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

    And then call the following in Application_Start:

    WebApiConfig.Register(RouteTable.Routes);
    

    Dot Net Core

    Add the Microsoft.AspNetCore.Session NuGet package and then make the following code changes:

    Startup.cs

    Call the AddDistributedMemoryCache and AddSession methods on the services object within the ConfigureServices function:

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

    and in the Configure function add a call to UseSession:

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

    SessionController.cs

    Within your controller, add a using statement at the top:

    using Microsoft.AspNetCore.Http;
    

    and then use the HttpContext.Session object within your code like so:

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

    you should now be able to hit:

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

    and then going to this URL will pull it out:

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

    Plenty more info on accessing session data within dot net core here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

    Performance Concerns

    Read Simon Weaver's answer below regarding performance. If you're accessing session data inside a WebApi project it can have very serious performance consequence - I have seen ASP.NET enforce a 200ms delay for concurrent requests. This could add up and become disastrous if you have many concurrent requests.


    Security Concerns

    Make sure you are locking down resources per user - an authenticated user shouldn't be able to retrieve data from your WebApi that they don't have access to.

    Read Microsoft's article on Authentication and Authorization in ASP.NET Web API - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

    Read Microsoft's article on avoiding Cross-Site Request Forgery hack attacks. (In short, check out the AntiForgery.Validate method) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

提交回复
热议问题