will httpcontext.session stay active if read? - c#

I know that Httpcontext.Session in MVC C# has a default timeout period of 20minutes.
But what if is read every 10minutes? Will this extend the timeout period? Or will it still time out after 20mins even if it is read within the 20minutes?
and part 2#. assuming the httpcontext will not time out if it is read within the timeout period, Is it ok to store a dbcontext in a httpcontext.session?
code like this:
public GenericDal()
{
if (HttpContext.Current.Session["unitOfWorks"] == null)
{
unitOfWorks = new UnitOfWork();
HttpContext.Current.Session.Add("unitOfWorks", unitOfWorks);
}
else
{
unitOfWorks = (UnitOfWork)HttpContext.Current.Session["unitOfWorks"];
}
}

It uses a sliding expiration, so when you access it, the timeout gets extended.
A session is considered active as long as requests continue to be made
with the same SessionID value. If the time between requests for a
particular session exceeds the specified time-out value in minutes,
the session is considered expired. Requests made with an expired
SessionID value result in a new session.
https://msdn.microsoft.com/en-us/library/vstudio/ms178581(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
And I wouldn't put the context in the session. The discussion about DBContext in the session is well documented -
One DbContext per web request... why?

Related

ASP.NET Webservice- SessionState not timingout

I have a web application that utilizes JQuery as my front end code and ASP.NET as my backend web service.
I set the web.config setting <sessionState timeout="1">. When the user logs in, the web service creates a session variable with the user name.
System.Web.HttpContext.Current.Session["UserID"] = user_id;
In my web service, I have a function that checks if the variable still exists.
[WebMethod(EnableSession = true)]
[ScriptMethod(UseHttpGet = true)]
public string GetSessionUserID()
{
string user_id = "";
if (System.Web.HttpContext.Current.Session["UserID"] != null)
{
user_id = System.Web.HttpContext.Current.Session["UserID"].ToString();
}
return user_id;
}
I have a JS function that calls the web service that calls GetSessionUserID().
$(document).ready(function () {
getSessionID();
setInterval(getSessionID, 3000);
function getSessionID() {
console.log("getSessionID");
$.ajax({
url: "photoapp.asmx/GetSessionUserID",
//data: ,
success: OnGetSessionIDSuccess,
error: OnGetSessionIDError
});
}
function OnGetSessionIDSuccess(data, status) {
console.log("Success OnGetSessionIDSuccess");
console.log(data);
var strUser = $(data).find("string").text();
console.log(strUser);
if (strUser == "") {
window.location = "login.html";
}
}
}
In the document ready function, I also call setInterval() which will check the session every 3 seconds.
When testing, getSessionID gets called every 3 seconds, but after a minute, the getSessionID user variable can be found. I want the redirect the user back to login.html after the minute is done. Why is the session variable still alive after a minute? What am I not understanding about ASP.Net session state? How can this be fixed?
Be aware that if you adopt SQL server to save the session state, then the session timeout events never get called, and you thus can't know or tell if the user actually has logged out.
The only possible solution then is to ensure that all web pages have some kind of heartbeat or routine that calls the server every minute or so, and when that stops, then you know the user is gone or closed the web page.
In your case? If you touch the server every 3 seconds, then the session timeout will be re-set and start over with 1 minute. You also don't mention if you using in-memory, or using sql server for session state.
If you want to jump back to the logon page? Then your 3 second js code has to get/grab the time of the last heartbeat you call every 3 seconds. So, that routine has to set a start time, and then every 3 seconds check the elapsed time. Keep in mind that if you use sql sessions, then not even the logon event will fire, nor will even the authenticated user event fire.
So, the first time you start running that routine, you need to set a session value with the start time.
However, to my knowledge, every web service call will re-set the session time out to start over to 0. session timeout gets re-set when no activity occurs. So, if the user is doing something (or your ajax calls are), then session timeout will never occur.
You have to set a start time. And then get the elapsed time from that. You session will never timeout as long as you have the web page hitting and talking to the server.

ASP .NET Core using InMemory Cache per user

I have a system where at some point, the user will be locked to a single page. In this situation his account his locked and he cannot be redirected to any other page and this is after authentication.
The verification is done using Page Filters accessing database. To improve performance I have used memory cache.
However, the result wasn't as expected because once the cache is used for a single user it will affect all the others.
As far as i know, you can separate caching using tag helpers per user but I have no idea if this is possible using code
public async Task<IActionResult> Iniciar(int paragemId, string paragem)
{
var registoId = Convert.ToInt32(User.GetRegistoId());
if (await _paragemService.IsParagemOnGoingAsync(registoId))
{
return new JsonResult(new { started = false, message = "Já existe uma paragem a decorrer..." });
}
else
{
await _paragemService.RegistarInicioParagemAsync(paragemId, paragem, registoId);
_registoService.UpdateParagem(new ProducaoRegisto(registoId)
{
IsParado = true
});
await _registoService.SaveChangesAsync();
_cache.Set(CustomCacheEntries.RecordIsParado, true, DateTimeOffset.Now.AddHours(8));
return new JsonResult(new { started = true, message = "Paragem Iniciada." });
}
}
here i only check first if the user account is blocked in the database first without checking cache first and then create the cache entry.
Every user will be locked because of this.
So my point is... Is there a way to achieve this like tag helpers?
The CacheTagHelper is different than cache in general. It works via the request and therefore can vary on things like headers or cookie values. Just using MemoryCache or IDistributedCache directly is low-level; you're just adding values for keys directly, so there's nothing here to "vary" on.
That said, you can compose your key using something like the authenticated user's id, which would then give each user a unique entry in the cache, i.e. something like:
var cacheKey = $"myawesomecachekey-{User.FindFirstValue(ClaimTypes.NameIdentifier)}";
Short of that, you should use session storage, which is automatically unique to the user, because it's per session.
There are several alternatives to the cache. For details please see this link that describes them in greater detail.
Session State
An alternative would be to store the value in session state. This way, the session of one user does not interfere with the ones of others.
However, there are some downsides of this approach. If the session state is kept in memory, you cannot run your application in a server farm because one server does not know of the others session memory. So you would need to save the session state in a cache (REDIS?) or a database.
In addition, as session memory is stored in the server users cannot change it and avoid the redirection that you try to implement. The downside is that this reduces the amount of users that your server can handle because the server needs to have a specific amount of memory per user.
Cookies
You can send a cookie to the client and check for this cookie when the next request arrives at your server. The downside of this approach is that the user can delete the cookie. If the only consequence of a missing cookie is a request to the database, this is neglectable.
You can use session cookies that are discarded by the server when the session expires.
General
Another hint is that you need to clear the state memory when a user signs out so that with the next sign in, the state is correctly set up for the new user.

Asp.net MVC Session timeout condition based handling

My MVC web application uses asp.net session management. Session has default timeout 20mins. On session timeout, user is redirected to the home page. My application uses SessionTimeout ActionFilterAttribute to handle session timeout.
SessionState is stored in server.
Problem:
Even if the session timout happens, when the user returns to a particular action method, I need to renew a session for that user and allow to continue instead of redirecting to home page.
I have tried to use the OnActionExecuting method in the SessionTimeout ActionFilterAttribute to identify the session timeout & if the action in the request is that particular action method, then allow the user to continue to that action.
But it seems to be not working. It just redirects the user to the Home page.
I am not sure how to proceed.
Session have bad problems like timeout and refresh not available, do authentication using forms authentication you can choose this custom authentication sample
Or Else use cookies
HttpCookie MyCookie = new HttpCookie("MyCookie");
// for remveing if already Exists adding new;
Request.Cookies.Remove("MyCookie");
if (Request.Cookies["MyCookie"] == null)
{
MyCookie["id"] = id.ToString();
Response.Cookies.Add(MyCookie);
}
else
{
MyCookie["id"] = id.ToString();
// Request.Cookies.Remove("MyCookie");
Response.Cookies.Set(MyCookie);
}
// retries
int id = Convert.ToInt32(Request.Cookies["MyCookie"]["id"]);
Thanks for your responses.
"Session cannot be renewed" once it has expired.
Instead of renewing the session, create a new session in the ActionFilters Attribute (SessionTimeout).
The solution for my problem is to create a new session and re-link it with the domain object/user so that the user can continue his journey. I have done this in my SessionTimeout ActionFilterAttribute, to create new session for only a particular request which has the particular controller/action.

Prolonging asp.net session enddate?

How is asp.net Session prolonging, does every request prolongs the end date of Session, and is it enough to call void() by ajax to extent Session end date by another period of time(default 20 min or so...)
public void ResetSessionTime()
{
}
or do i have to invoke session in some way:
public void ResetSessionTime()
{
User currentUser = HttpContext.Current.Session[userSessionKey] as User;
}
how does simple request extend session end date?
This question claims every post-back prolongs session...
This MSDN about Session State Providers :
"Each session created by ASP.NET has a timeout value (by default, 20
minutes) associated with it. If no accesses to the session occur
within the session timeout, the session is deemed to be expired, and
it is no longer valid."
How does request access the session exactly?
THIS QUESTION: Keeping session alive C# does not answer how session end date is prolonged by request, only a opinion on how to keep session alive from client side
EDIT:
According to this article, method needs to be extended from IHttpHandler, in order to access current session...
public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Session["KeepSessionAlive"] = DateTime.Now;
}
}
Every time you make a request, the session timeout is reset. A request can be a page load or something like an ASYNC call.
Take a look at this question for an example of how to keep the session alive by periodically making AJAX calls to the server. (Keeping ASP.NET Session Open / Alive)

asp.net Global variables and session variable lose value after 5-15 minutes

I am not sure why but only after a certain amount of time, My web application global variables lose value and also the session variables as well. I set in the web config file <sessionState timeout="60" />. This is on my local host i have not put this out on a web server yet, could this be the cause?
with inproc session state, if the app pool recycles or shuts down, your session information is gone. check iis settings for when app pool recycles happen. i believe there is a default to shut down the app pool after 20 minutes of inactivity. there are many other reasons this can happen. if you need session to live beyond the life of your app pool, you should take it out of proc and run in state server or database or something else custom.
In case it runs in IIS, do you have Regular Time Interval (minutes) or Idle Time-out (minutes) to a low value? These settings can be found under Advanced Settings... of your application pool.
This may not solve your problem but you can add the following to the page's OnInit to determine whether or not the session has actually timed out or not:
override protected void OnInit(EventArgs e)
{
// Initialize the base Page class.
base.OnInit(e);
//If the session exists
if (Context.Session != null)
{
// IsNewSession indicates the session has been reset or the user's session has timed out.
if (Session.IsNewSession)
{
// new session, check for a cookie.
string cookie = Request.Headers["Cookie"];
// If there is a cookie does it contain ASP.NET Session ID?
if ((null != cookie) &&
(cookie.IndexOf("ASP.NET_SessionId") >= 0))
{
// Since it's a new session but an ASP.NET cookie exists, the session has expired. Notify the user.
throw new Exception("Your session has timed out. ");
}
}
}
}

Categories