Specifying read-only session in ASP.NET MVC - asp.net-mvc

Is there any way to specify that a given Controller or Action uses Session state in a read-only manner? In "old" ASP.NET we used to do something like this:
<%# Page EnableSessionState="ReadOnly" %>
Is there an ASP.NET MVC equivalent? I'm looking to allow my application to serve multiple requests from the same client simultaneously, and turning off session completely is -not- an option in my case.

In Asp.Net MVC3 there is now a SessionStateAttribute that you can decorate your Controller with to force all actions into Read-Write, Read-only, or No session mode.
http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute(v=VS.98).aspx

A similar question was asked here: Disable Session state per-request in ASP.Net MVC
The accepted answer deals with creating a custom route handler that ultimately skips binding to the session. This doesn't exactly answer your question (which is how to declare multiple actions to use readonly session access), but it seemed relevant enough to mention.

This could be a bit tricky--my understanding is setting up the session state is something that happened at the IHttpHandler level. With custom handlers, you could specify the session state by using marker interfaces, like IReadOnlySessionState to declare that it only needs readonly session state. You could try appending that to your controller and see how it flies. I'd suspect it won't because ASP.NET mvc controllers happen well after the IHttpHandler is wired up, but it is worth a shot.
Another solution might be to wrap the session state variables in your own class, and expose a readonly version to enforce readonly. Accessing it across multiple requests shouldn't be a problem, but you are correct that you can get race conditions and such if you start trying to write to the same session variables from multiple angles.

What about setting the data you want to be "Read Only" as static in your Model? In this way you could have simultaneous requests to MVC with the same data.

Related

ASP.NET MVC Session and SessionStateBehavior

All:
I have been searching high and low for an answer to this, so forgive me if this is a dupe, I just can't seem to find the right answer.
Let's say you have an ASP.NET MVC Controller marked with the [SessionState(SessionStateBehavior.Disabled)]
attribute. Does calling actions on this controller "refresh" the session state, keeping it "alive"? Specifically, I have a AJAX request calling a controller to keep the session "alive" since the application is a single page application driven by javascript, and I don't want the users session to die, so every 30 seconds I make a call up to this controller. Similarly, would it stay alive if the controller was marked SessionStateBehavior.ReadOnly? Finally, is using an ASP.NET MVC Controller for this purpose not the best way (is there a better way)?
Thanks!
Session state will be kept alive automatically with no attributes on the action, depending on how the web.config is configured. To configure it, see here: http://msdn.microsoft.com/en-us/library/h6bb9cz9(v=vs.100).aspx
A controller should be okay, but you may want to look into Web API as it'll offer a few more features in this scenario: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

ASP MVC vs. WebForms: using SessionState for user logon

i've a question regarding handling of user logon while porting an application to MVC:
in the "old" WebForm days, developers simply used the SessionState object to set a user to logged-on, by -for example- simply putting the userobject into the SessionState (and this userobject holds simple properties like name/lastlogon/etc.)
this stuff worked very well for us, and i've seen lots of applications doing it that way
yes, i know there is this MembershipProvide-thingy, but i've never used it
Now, in MVC, everybody tells me that "using SessionStat for this is bad" and "apps built that way are flawed in design" and that "there are tons of security risks" and so on.
I've used this method because it worked for the app very reliable, it was simple to implement and it covered all stuff we need.
(Sure, there is the thing with recycling web worker process and emptying the session - but thats not a problem in our case, since the app runs for each country on a dedicated machine)
I've read tutorials, telling me to put that stuff in the DB and -attention- doing a request to the DB to check if the user is logged in, per EACH request? But: Under no circumstances, this is a doable way since i want to keep DB requests on a minimum.
So my question is:
A) whats wrong using this way also in the new MVC app?
B) whats the best way to handle this scenario in a newly built MVC app?
Regarding the session-in-DB-idea: instead of doing this, i'd rater setup an additional service, like a "session-manager" thats get query over the network, but such simple requests should not go to the DB - isn't that a good idea?
Any idea, hint /etc. is highly appreciated since this scenario is really confusing me :-X
A)
A fundamental principal of the asp.net mvc framework is that its stateless. Data is passed around using http requests and sent to the views in viewmodels. Web forms tried to maintain state with viewstate etc thats why you would have seen the logged in user in session approach. Thats not to say session shouldnt be used completely in asp.net mvc, there are some circumstances when it can be useful. Like maintaining a 3 step form process that has to be persisted on the last step. But generally we already have a recommended way to handle the user logins, and thats forms authentication
B)
For accessing the user object, you can create a custom identity implementing the IPrincipal interface and add the required user fields you need. Then set the custom identity in a global filter and access it in your action results. Regarding not wanting to query the database for every request, why dont you just call it for the initial request, then cache the result until the user is updated where you then can reload the object and set it in the custom identity again.

How to prevent MVC ActionFilterAttribute from being cached?

I have a MVC API ActionFilterAttribute that does a permissions check using the Entity Framework. I've found that because of ActionFilterAttribute caching the EF connection is often broken. You can find other questions about here. So does anyone know how to prevent caching in ActionFilterAttributes?
Just a Note to your title: I would say that Action Filters in MVC are not cached, they act as singletons (as explained in the link you've provided).
As the answer to your needs I would say use Request based persistence. Because you would most likely want to do some stuff like:
- OnActionExecuting() (e.g. open Transaction)
- OnActionExecuted() (commit or rollback)
So put your object (_unitOfWork) into
System.Web.HttpContext.Current.Items
You can access it form the singleton methods, while operating on request dependent objects. I am doing it similar way with NHibernate Session

Asp Net MVC 3 - Moving through Actions and Views, SessionState

How can I keep some values between different Views in MVC 3?
I tried using TempData and HiddenField to keep these values but in our hosting this tecnique seems to have short life so exceptions are coming out furthermore if user uses Back button every starts to fail.
I would like to understand the better way to keep values between views in MVC 3, thanks in advice!
By design, MVC3 TempData values are removed after they are used.
The most simple answer is to use the Session object directly in your controllers.
There are other related questions with detailed answers such as these:
Session variables in ASP.NET MVC
Asp.Net MVC and Session
Your question is about the lifecycle of objects in between requests. It's important to understand that webapplications are used over the HTTP(S) protocol which is a stateless protocol. This means that every request is a completely new request for the webserver and there's no state shared between requests.
However it would be foolish to send the credentials of a user to the server each and every time so a webserver can create a thing they call a Session (and session-state). This object is an object that remains available for the lifetime of the session of the current user (most of the times from logging in until logging out). You can use this object to store items that you wish to share over various requests of the same user.
If the values you're trying to keep are specific to the page you can probably use a hidden field or something like that. However if the data is more related to the user than to a specific page and it must have a lifecycle longer than a single request then sessionstate is the best place to store the data.
You could use the Session (as you mention in your title and tags). Or store a cookie on the user's machine

Performance logging for WebForms pages via MVC routing

We have a legacy application that is part-ASP.NET WebForms and part-ASP.NET MVC.
In order to give all URLs an MVC "style" we've registered a set of routes to map the desired URLs back to the WebForms URLs.
e.g.
routes.Map("somemapping", "NiceUrl/{page}").To("~/UglyUrl/UglyPath/{page}.aspx");
On the MVC Controllers we have implemented performance logging of action methods by way of a custom attribute that inherits from ActionFilterAttribute and overrides OnActionExecuting and OnActionExecuted.
We would like to implement similar logging for the WebForms pages. Is it possible to hook into the routing part and log from there?
Using a System.Diagnostics.StopWatch could solve your problem at a global level.
Here is my proposed solution:
1. In the application BeginRequest instantiate a new instance of StopWatch.
2. Call the start method on the stop watch instance.
3. Place the stop watch in the HttpContext.Current.Items collection
4. In the application End Request, get the StopWatch instance from the httpcontext items, call the stop method, and used the "Elapsed" property of your choice to get the necessary time data that you would like to store
this will provide one single place where you can measure the processing time of all requests, mvc and webforms.

Resources