2

I am creating a web service with web api controller. I want to be able to create a session and check the status of the session. I have the following:

Controller:

public string Get(string user, string pass)
{
        bool loginValue = false;
        loginValue = UserNamepassword(user, pass);

        if (loginValue == true)
        {
            HttpContext.Current.Session.Add("Username", user);                
            //session["Username"] = user; 
            //session.Add("Username", user);
            if ((string)HttpContext.Current.Session["Username"] != null)
            {
                HttpContext.Current.Session.Add("Time", DateTime.Now);

                return "Username: " + (string)HttpContext.Current.Session["Time"] + (string)HttpContext.Current.Session["Username"];
            }
            return "Logged in but session is not availabe for " + (string)HttpContext.Current.Session["Username"];
        }            
        else
            return "Login failed for " + user;
}

WebConfig

public static void RegisterRoutes(RouteCollection routes)
    {
        var route = routes.MapHttpRoute(
            name: "SessionApi",
            routeTemplate: "api/{controller}/{user}/{pass}",
            defaults: new { user = RouteParameter.Optional, pass = RouteParameter.Optional }
        );
        route.RouteHandler = new MyHttpControllerRouteHandler();
    }
    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);
        }
    }

Global.asax.cs

WebApiConfig.RegisterRoutes(RouteTable.Routes);

When I run this code I keep on getting null reference in the session.

HttpContext.Current.Session.Add("Username", user);                
//session["Username"] = user; 
//session.Add("Username", user);

Does anyone knows why I cannot set the session variable to anything. It does not matter which method I use non of the three are working. The code was taking from another post.

Program_ming
  • 95
  • 2
  • 2
  • 9
  • 1
    Do not use Session in web Api. That defeats the purpose. – Shyju Dec 03 '14 at 16:01
  • I have to. I do not know other way. I am new to Web API. still researching on it. but for the time beng I need to use it – Program_ming Dec 03 '14 at 16:33
  • possible duplicate of [ASP.NET Web API session or something?](http://stackoverflow.com/questions/11478244/asp-net-web-api-session-or-something) – Laurent S. Feb 18 '15 at 10:19

3 Answers3

11

This is where semantics often clouds the discussion. People confuse the Session object with statelessness. And often say: 'don't use session because it isn't stateless!'.

However they really mean that you should strive to have your the restful calls to be idempotent, meaning they don't change their behavior depending on whatever it is you do in the background.

Session, or the runtime-cache, or whatever it is you use to cache data, has no effect on your stateless design, because really, what's next? Your database is statefull too? And you shouldn't read data from that? Nonsense obviously; your underlying storage, if it's in-memory or on disk has no reflection on your state to the client.

So use, by all means, the session object as Ben Robinson pointed out. But never let the fact if something is IN session return a different result then when something is OUT of session.

Gerben Rampaart
  • 9,853
  • 3
  • 26
  • 32
  • So what if I would use the session to store a bearer token for further validation in later requests? The statelessnes is here that the person who makes the request is authorized or not authorized hence resulting in different results – Florent Mar 22 '22 at 09:04
  • @florent No that doesn't break idempotency. A 401 is one of the possible return states of your api. That code as a possible request outcome should be documented in your api and known to the user. – Gerben Rampaart Mar 24 '22 at 18:15
7

This is by design in Web API because it is designed for creating restful web services. To be truly restful a service should not have any kind of state, i.e. /myserver/somendpoint/5 should have the same result for any request with a given verb.

However if that doesn't suit you, you can enable session in web API by adding following to global.asax.

protected void Application_PostAuthorizeRequest() 
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
Ben Robinson
  • 21,601
  • 5
  • 62
  • 79
2

Please, don't!

Web API is supposed to be stateless, RESTful, etc. By using State you're defeating its whole purpose.

Appulus
  • 18,630
  • 11
  • 38
  • 46
Mihai Dinculescu
  • 19,743
  • 8
  • 55
  • 70
  • 3
    I hear this in a lot of posts... REST is supposed to be stateless. But using session seems to me just a convenience for performance enhancements. e.g. If i have am forced to do 2 queries (e.g. look up a user and then look up their resources) why do that every REST call. Why not cache the results from the first look up keep them around for 15 minutes under the assumption that people request data in mini spurts. Then throw those results away after say 15 minutes of non-use. How is that defeating the whole purpose? How does forcing the api to look up the database making it MORE restful? – frigon May 31 '16 at 18:42
  • @frigon, yes caching results in your scenario is useful. Broadly, you could do that in-memory within the same process handling the request (non-RESTful), or delegate that to another process/server (RESTful). One clear advantage to me to use the latter is scalability: think about a server farm handling multiple requests from the same client if you were using the non-RESTful approach. [Here's a good answer on this topic](http://stackoverflow.com/questions/3105296/if-rest-applications-are-supposed-to-be-stateless-how-do-you-manage-sessions#answer-3105337) that may clarify things further. – rtorres Jul 06 '16 at 21:17
  • If you say 'stateless' then you mean when accessing data through an endpoint and always getting the same result. When you do authentication and a user gets denied the requested ressource doesn't it make the api also not stateless? There are definetly use cases where you would want to use a session inside an api otherwise I cannot imagine why we even get the ability to even use the session in the first place. – Florent Mar 22 '22 at 09:44