I am not sure if this is officially supported, but you can access the session in the http context via the HttpRequestMessage properties bag. Look up the context with the following key: "MS_HttpContext"
Which ties you to ASP.NET hosting of course. And defeats the purpose of designing a stateless service (from a transport perspective).
Also keep in mind that the asp.net session feature is also not very efficient. And since there is no built-in support in web api (for a good reason) none will update the session timeout for you.
The purpose of keeping session in my particular case is to authenticate the user. Which commonly is what sessions are used for, i cannot see why this should tamper with keeping the API stateless.
For instance a user posts a comment in json
{Author: someAuthor, Comment: wow a great comment}
The application will need to handle whether or not the user is allowed to use someAuthor as the author.
For authentication - you typically use an identifier cookie (like FormsAuthentication does). But not the ASP.NET session state feature.
Keeping state in memory is not reliable (and limits you to a single server), which only leaves storing out of process - that in turn means 2 database roundtrips for every web request. Just to keep the session mechanism happy.
If it is only for authentication, use a simple cookie. If it is for user state, you should rather send that as part of the request (or think about writing your own custom cookie / backing mechanism). ASP.NET profile might be another (more efficient) alternative.
hmm, i might be wrong about this, but placing a cookie at the user which identifies him and allows the server to look up whether he is logged in or not, in my oppinion that's pretty much the essential of a session, even though microsoft calls it an identifier
cookie.
But okay, i do not have much knowledge about this particular feature, and I will look in to it. but before hand, is it possible to acces the the stored user name in within the controller method, since a simple logged in or not attribute is not sufficient
for my needs. In most cases i need to acces my database to figure out if a user is authenticated?
an authentication cookie is self sufficient - the possession of that cookie proves that the user is authenticated. In addition this cookie can contain additional information like the username or roles.
The session mechanism is using a cookie that contains a GUID - this GUID is used to contact some sort of data store (SQL Server is really the only option here if you need something robust).
You see the difference?
and btw there is no need to implement the authentication cookie mechanism yourself - that's exactly what Forms Authentication in ASP.NET or Session Authentication in WIF does.
Ah - and yes - once you use the ASP.NET mechanisms the way they are intended, you can retrieve the user name and the fact he is authenticated from Request.GetUserPrincipal().
Due to various reasons, I am not recommeding to use Session in WebAPI. But on the other hand this is also true that you cannot ignore peoples which are much used to Session. So, here is quick way to add Session in Web API,
public class MvcApplication : 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();
......................................................
......................................................
}
......................................................
......................................................
}
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);
}
}
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;
}
}
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
Marked as answer by imran_ku07 on Mar 25, 2012 04:56 PM
TauAU
Member
6 Points
4 Posts
Web API how to acces session?
Mar 14, 2012 06:26 PM|LINK
Hey everyone,
I'm writing here because I couldn't find any informative information elsewhere. It seems that i can't find any session property in the Api Controller.
Is it possible at all to access some sort of session attribute in the new Web Api from within a Api Controller method?
davebettin
Member
313 Points
94 Posts
Re: Web API how to acces session?
Mar 14, 2012 06:39 PM|LINK
I am not sure if this is officially supported, but you can access the session in the http context via the HttpRequestMessage properties bag. Look up the context with the following key: "MS_HttpContext"
@dbettin
dbaier
Member
262 Points
65 Posts
MVP
Re: Web API how to acces session?
Mar 14, 2012 07:53 PM|LINK
Which ties you to ASP.NET hosting of course. And defeats the purpose of designing a stateless service (from a transport perspective).
Also keep in mind that the asp.net session feature is also not very efficient. And since there is no built-in support in web api (for a good reason) none will update the session timeout for you.
So all in all - it is not recommended.
dominick
_____________________________
Dominick Baier - http://www.leastprivilege.com
davebettin
Member
313 Points
94 Posts
Re: Web API how to acces session?
Mar 14, 2012 07:58 PM|LINK
Yes, concur will all of these statments. There is definitely a reason it is hidden deep in the fx.
@dbettin
TauAU
Member
6 Points
4 Posts
Re: Web API how to acces session?
Mar 14, 2012 09:39 PM|LINK
The purpose of keeping session in my particular case is to authenticate the user. Which commonly is what sessions are used for, i cannot see why this should tamper with keeping the API stateless.
For instance a user posts a comment in json
{Author: someAuthor, Comment: wow a great comment}
The application will need to handle whether or not the user is allowed to use someAuthor as the author.
dbaier
Member
262 Points
65 Posts
MVP
Re: Web API how to acces session?
Mar 14, 2012 09:53 PM|LINK
Well - that's not entirely true.
For authentication - you typically use an identifier cookie (like FormsAuthentication does). But not the ASP.NET session state feature.
Keeping state in memory is not reliable (and limits you to a single server), which only leaves storing out of process - that in turn means 2 database roundtrips for every web request. Just to keep the session mechanism happy.
If it is only for authentication, use a simple cookie. If it is for user state, you should rather send that as part of the request (or think about writing your own custom cookie / backing mechanism). ASP.NET profile might be another (more efficient) alternative.
dominick
_____________________________
Dominick Baier - http://www.leastprivilege.com
TauAU
Member
6 Points
4 Posts
Re: Web API how to acces session?
Mar 15, 2012 08:02 AM|LINK
hmm, i might be wrong about this, but placing a cookie at the user which identifies him and allows the server to look up whether he is logged in or not, in my oppinion that's pretty much the essential of a session, even though microsoft calls it an identifier cookie.
But okay, i do not have much knowledge about this particular feature, and I will look in to it. but before hand, is it possible to acces the the stored user name in within the controller method, since a simple logged in or not attribute is not sufficient for my needs. In most cases i need to acces my database to figure out if a user is authenticated?
dbaier
Member
262 Points
65 Posts
MVP
Re: Web API how to acces session?
Mar 15, 2012 08:07 AM|LINK
Well - there is a significant difference -
an authentication cookie is self sufficient - the possession of that cookie proves that the user is authenticated. In addition this cookie can contain additional information like the username or roles.
The session mechanism is using a cookie that contains a GUID - this GUID is used to contact some sort of data store (SQL Server is really the only option here if you need something robust).
You see the difference?
and btw there is no need to implement the authentication cookie mechanism yourself - that's exactly what Forms Authentication in ASP.NET or Session Authentication in WIF does.
dominick
_____________________________
Dominick Baier - http://www.leastprivilege.com
dbaier
Member
262 Points
65 Posts
MVP
Re: Web API how to acces session?
Mar 15, 2012 08:09 AM|LINK
Ah - and yes - once you use the ASP.NET mechanisms the way they are intended, you can retrieve the user name and the fact he is authenticated from Request.GetUserPrincipal().
http://www.leastprivilege.com/ASPNETWebAPISecurity2IdentityArchitecture.aspx
dominick
_____________________________
Dominick Baier - http://www.leastprivilege.com
imran_ku07
All-Star
45785 Points
7698 Posts
MVP
Re: Web API how to acces session?
Mar 17, 2012 04:07 AM|LINK
Due to various reasons, I am not recommeding to use Session in WebAPI. But on the other hand this is also true that you cannot ignore peoples which are much used to Session. So, here is quick way to add Session in Web API,
public class MvcApplication : 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(); ...................................................... ...................................................... } ...................................................... ...................................................... } 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); } } 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; } }Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD