Web Api 2 Session - c#

I cannot get session data from while in web api 2. I have verified that the cookie is sending in fiddler.
I know that web api 2 best practice is to be stateless, but due to requirements on a project it is now necessary to be state-full.
I have tried this link.
WebAPI 2 attribute routing enable session state
var session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current)
With the above solution I am getting a null exception on that function.
I also tried replicating the way of doing this the way you would in the old web api by modifying the requesthandler from the route, but that is not available in web api 2.
I currently set some session variables in mvc5. This works and the session stays, but anytime I am trying to use session while in web api 2 the below is null.
HttpContext.Current.Session

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

If PostAuthorizeRequest doesn't work, then try BeginRequest.

Related

how does host differentiate MVC request and Web API request

I'm new to asp.net mvc and web api. I'm reading a book which says:
ASP.NET MVC uses: System.Web.HttpRequest
and Web API Equivalent is System.Net.Http.HttpRequestMessage
and below is a picture that describes the request and result flow of web api
So my question is, how does hosting environment(which will typically be IIS) know that it should create a HttpRequestMessage object to represent the request from the client? I mean if the application is a MVC application, IIS should create a HttpRequest object instead of HttpRequestMessage, so how does IIS know which one to create?
As you can see from the picture you posted, the HttpRequestMessage exists only inside the "hosting" environment, web browser client does not know anything about that.
In the "hosting" world, IIS app pool is running the code you have built and deployed which knows very well wich framewok you are using as your code also contains the using assemblies you listed, System.Web... or System.Net...
Consider that even if you have shown separation between hosting, Controller and Action, all of that is running in same App Pool in IIS which, again, runs your code so knows what it is about as your IL assemblies were built from your specific source code.
I am not sure if I understand your question but this might be what you're looking for:
I mean if the application is a MVC application, IIS should create a
HttpRequest object instead of HttpRequestMessage, so how does IIS know
which one to create?
You must remember how you differentiate between a normal MVC Controller and a Web API Controller...
WebAPI Controllers enforces this annotation [ApiController] and must inherits from ControllerBase:
[ApiController]
public class PeopleController : ControllerBase {
//Your API methods here
}
A normal MVC Controller only inherits from Controller base class:
public class PeopleController : Controller {
//Your Action methods here...
}
Those already create configuration for your APP which becomes easier for you Hosting environment to know what is going and what to return when.
I hope you find this helpful.

Does SessionID change for each call to webservice?

I don't understand the notion of session for webservices. In one hand you can allow session in DataAnnotation like that :
[WebMethod(EnableSession = true)]
In the other and you can configure the session state in IIS :
So I put Session State in process and set the delay for 20 minutes.
Then in my webservice I try to get the session ID like that :
return HttpContext.Current.Session.SessionID
I use a winform to get this information and call the webservice.
And the session ID Change at every call. I don't understand why, beaucoup SessionState is set to 20 minutes...
May I'm in wrong way ? Can you explain me ?
Is SessionID correspond to the Session State in IIS ?
There must be something that connects the request to a particular session. Usually a cookie is used for that. This cookie is sent along with the response, so the calling application must remember that cookie and send it along with the next request. Without cookie the request is handled as if it's a new session.
A browser handles this by default (unless specifically switched off), for an other application you need to do cookie management yourself. For this you need to use a single CookieContainer that will be shared among your requests.
See the link in the answer by Marius for more details.
I was thinking of a solution, but then I found this post :
How to keep session alive between two calls to a web service in a c# application?
I hope this helps.
If you want to keep your sessionID same througout users session life time you should add a global.asax file to your web project and implement Session_Start method.
Please check this link:
https://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

Getting virtual URL in C#

We have two virtual URL's that is using webseal for our intranet appication such as,
https://third-party-site.com/myapplication/Default.aspx
https://my-application.com/Default.aspx
which internally points to https://original-url.com:8080/Default.aspx after successful authentication from their respective sites.
I want to get the current URL from Default.aspx page. I have tried with Request.Url but it is returning the original URL. ie. https://original-url.com:8080/Default.aspx
For eg. if I access Default page from https://third-party-site.com/myapplication/ then it should return the current URL as https://third-party-site.com/myapplication/Default.aspx.
Currently it is returning as https://original-url.com:8080/Default.aspx
Is there any way to get the virtual URL itself?
Request.Url returns https://original-url.com:8080/Default.aspx because this is what IIS receives.
You don't describe your infrastructure but I believe you have load balancer or some kind of rouer before the IIS. It is often (de facto a standard) that those services inject http header called X-Forwarded-For. You can try get that by:
if (Request.Headers["X-Forwarded-For"].Count > 0) { ... // use the real domain }
If that fails you should check documentation of your service handling the requests before the IIS.

WebAPI Cookies with ReportViewerWebControl

I have an MVC application that also includes an ASP.Net WebForm to host the MS ReportViewer Web Control. We make extensive use of WebAPI to allow for client posting from Knockout viewmodels client side.
In this application, we're making use of cookies to maintain a few minor pieces of user data--a GUID, an int, and a bool.
What we see at present is that the application works correctly until a user opens the ReportViewer. At that point, we're no longer able to read any cookies from the request headers. This has been consistently reproduced in several browsers.
Examination with Fiddler has revealed that the cookies are properly posted to the server. In the first case, the cookie value is as follows:
theCulture=en-US; ASP.NET_SessionId=uhmquapd1bgghpmfgy24oodf; .ASPXAUTH=6BC2F53F9CA0CF5A437998B206B564B28B5AB362153E6E0629C9142F9E3A0285494F674716A126E4632A932BCE12CE094FE590911CE5E97EA42D0C610A44D8462A15BA9A54760883DDF712B5B199C136413667954F094FEBA2A57826BC84702A4D90D7382E360594ABC2F9EBDCEE696B4662077F; special=theId=1077b59a-100d-429b-b223-f8f0508fdc27&staffingId=77096&isBackupUser=False
In the second case, after opening the ReportViewer, our cookies are as follows:
theCulture=en-US; ASP.NET_SessionId=uhmquapd1bgghpmfgy24oodf; .ASPXAUTH=6BC2F53F9CA0CF5A437998B206B564B28B5AB362153E6E0629C9142F9E3A0285494F674716A126E4632A932BCE12CE094FE590911CE5E97EA42D0C610A44D8462A15BA9A54760883DDF712B5B199C136413667954F094FEBA2A57826BC84702A4D90D7382E360594ABC2F9EBDCEE696B4662077F; special=theId=1077b59a-100d-429b-b223-f8f0508fdc27&staffingId=77096&isBackupUser=False; /Reserved.ReportViewerWebControl.axd%3FOpType%3DSessionKeepAlive%26ControlID%3Dc3b959ab1a7c42e6a9fed5d2762a8c86_SKA=1
At which point we can no longer read them from WebApi. The method that returns the cookie in the WebAPI Controller is this:
public OurType GetApproverInfo()
{
OurType data = new OurType();
CookieHeaderValue cookie = Request.Headers.GetCookies("special").FirstOrDefault();
CookieState cookieState = cookie["special"];
data.Id = Guid.Parse(cookieState["theId"]);
data.StaffingId = Int32.Parse(cookieState["staffingId"]);
data.IsBackupUser = bool.Parse(cookieState["isBackupUser"]);
return data;
}
Anyone else seen something like this?
UPDATE: I've just learned that creating a cookie with a leading / in the name causes the same behavior in WebAPI.
What I see is that the ReportView is messing up the cookie. Probably you're setting up the cookie somewhere in the WebApi that has not the same pipeline execution sequence as the ReportView Handle.
Heres the WebApi life cycle: ASP.NET WEB API: HTTP MESSAGE LIFECYLE
But, you can override the ReportViewerServerConnection, using IReportServerConnection, and there persist yours cookie pattern.
Take a look here: Web.config Settings for ReportViewer
Another way should be setting up the cookie in a Custom IHttpModule, integrated into the ASP.NET pipe line, and then target both, WebApi and ReportView

Can not access IHttpRequest within ServiceStack Mvc Application

Sorry for my lack of understanding regarding the web stack but this has been haunting me for a couple days.
I am trying figure out how to access Request as a IHttpRequest within the web controllers of the https://github.com/ServiceStack/SocialBootstrapApi example.
It is currently a MVC3 app with ServiceStack's MVC PowerPack. My request always resolves to a System.Web.HttpRequest. I created an extension method on IHttpRequest to check if the current request is coming from a mobile device but it never gets picked up because all my requests are System.Web.HttpRequests instead of a ServiceStack.ServiceHost.IHttpRequest. any help would be great!
You can do something like
var httpReq = System.Web.HttpContext.Current.ToRequestContext().Get<IHttpRequest>();
to turn the request from System.Web.HttpRequest into a ServiceStack.ServiceHost.IHttpRequest.
The requests going into the Controllers of the SocialBootstrapApi examples don't come through the 'ServiceStack pipeline'. The Controllers do inherit from ServiceStackConroller but I think its purpose is to share Session data between MVC and ServiceStack. The ServiceStackContoller doesn't take over the request/response like a request going into the /api path which is handled entirely by ServiceStack in the example project.

Categories