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
Related
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 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
problem:
On first full page request, my controller invokes an applicationServices Layer (Web Service Proxy to my business tier) in order to populate a collection of current services that is stored in my own controller base class property. This is then to be displayed within a view.
Everything within the context of that controller has access to this "Services Collection". Now when i make further calls to the same action method via an AJAX Call, i obviously hitt a different instance of that controller meaning my services collection is empty.
So other than re-getting the whole collection again, where would i store this collection so it gets persisted between ajax requests? Should i persist it as a seperate DomainModel Object, Session object?....as ViewData is not working for me obv. Excuse my MVC ignorance :)
Any help would be greatly appreciated :)
The web is essentially stateless and MVC helps you to go down to the metal, that is, MVC does not try to make something stateful that isn't, which is mostly the path of ye olde ASP: Each request is a request of it's own and it shouldn't know anything about any other request that has been performed in the past.
I feel it is easiest to go down exactly that route, because it it tends to stay clean, fast and helps you in adhering to best practices such as separation of concerns.
AJAX takes this a step further: The idea of AJAX is that a simple 'delete' operation can be implemented as such, i.e. you only need to authorize and perform one very small query on the persistence layer. That's it. You don't even need to pass a modified page back to the user. A simple machine-readable success/error indication via JSON is sufficient.
If you start to pull lots of services around for small AJAX requests, you really lose most of what it's good for.
I'd also suggest you don't store a bunch of services in a base controller. Chances are that for most requests, you will only need a small subset of these. It's best practices to retrieve only those service you absolutely positively need.
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.
A page executes a number of tasks and takes a long time to process. We want to give the user feedback as each task is completed.
In ASP.NET webforms we used Response.Flush()
What way would you a approach this in ASP.NET MVC?
You can still use Response.Write() and Response.Flush() for whatever status you want to send down the wire. Or if you have your progress thingy in a user-control, you could do something like:
this.PartialView("Progress").ExecuteResult(this.ControllerContext);
this.Response.Flush();
from your controller while doing your lengthy operation in the controller's action method.
It's up to you to choose this or the client-side approach as mentioned in the comments here, just wanted to point out that server-side is still possible.
I would suggest to use AJAX for displaying progress. See links for ideas:
Real-Time Progress Bar With ASP.NET AJAX
Using jQuery Plugins with ASP.NET
Ajax Progress Bar Control
There are two basic ways:
Poll a server page that returns the status, then once the operation is done, redirects to a results page. MVC is nothing to do with this way, you'd need to use a server variable to store objects/status - this is a way that's more relevant to a standard Asp.NET application as you're (presumably) using session variables etc. anyway.
AJAX call from the client to a webservice on the server. Asp.NET MVC is going to be rolling the jQuery framework in, so use that for the client call and event handling for the response. This would be more in the spirit of MVC which doesn't/shouldn't use session state etc.
Me personally I would consider two optoins:
redirect to wait page(s), then fire actions
Do it ajax style
You can make it in client side. In each step, you set some session variable with the current step. Then, You make another action in your controller say called: "GetProgress" and assign a view and URI for it.
In the action, you will check this session and return the current progress of your task. In the client side, make a timer (i.e setTimeOut) and you invoke the URI of the later controller action every specific amount of time - 1 second or so. That is it.