Session state is a core mechanism in ASP.NET for maintaining user-specific data across multiple HTTP requests. By default, ASP.NET sessions expire after 20 minutes of inactivity, but most applications need to adjust this based on their specific requirements. This guide covers every method to configure session timeout, the different session state modes, sliding versus absolute expiration, and best practices for reliable session management.

Understanding ASP.NET Session State

When a user visits an ASP.NET application, the server creates a unique session identified by a Session ID (typically stored in a cookie named ASP.NET_SessionId). This session acts as a server-side dictionary where you can store objects that persist across requests for that specific user.

Session Lifecycle

  1. Creation: A new session is created on the first request (or when Session is first accessed).
  2. Active: The session remains active as long as the user sends requests within the timeout window.
  3. Sliding Expiration: By default, each request resets the timeout countdown.
  4. Expiration: If no request is received within the timeout period, the session is marked as expired and its data is eligible for cleanup.
  5. Abandonment: Code can explicitly end a session with Session.Abandon().

Default Session Konfiguration

The default ASP.NET session configuration is:

  • Timeout: 20 minutes
  • Mode: InProc (in-process, stored in server memory)
  • Cookieless: false (uses cookies for session ID)
  • Cookie Name: ASP.NET_SessionId
  • Expiration Type: Sliding

Method 1: Configuring Session Timeout in web.config

The most common and recommended way to set the session timeout is through the web.config file.

Basic Timeout Konfiguration

<configuration>
  <system.web>
    <sessionState
      mode="InProc"
      timeout="30"
      cookieless="false"
      cookieName="ASP.NET_SessionId" />
  </system.web>
</configuration>

The timeout attribute is specified in minutes. Common values:

ScenarioRecommended Timeout
High-security applications (banking)5-15 minutes
Standard web applications20-30 minutes
Internal/intranet applications30-60 minutes
Long-form data entry applications60-120 minutes
Kiosk or shared terminal applications5-10 minutes

Complete sessionState Konfiguration

<configuration>
  <system.web>
    <sessionState
      mode="InProc"
      stateConnectionString="tcpip=127.0.0.1:42424"
      sqlConnectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI"
      cookieless="false"
      cookieName="ASP.NET_SessionId"
      timeout="30"
      regenerateExpiredSessionId="true"
      sqlCommandTimeout="30"
      useHostingIdentity="true">
    </sessionState>
  </system.web>
</configuration>

Key Attributes Explained

AttributeDescriptionDefault
modeWhere session data is stored (InProc, StateServer, SQLServer, Custom, Off)InProc
timeoutMinutes of inactivity before session expires20
cookielessWhether to use cookies or URL rewriting for session IDfalse
cookieNameName of the session cookieASP.NET_SessionId
regenerateExpiredSessionIdGenerate a new ID when an expired session ID is receivedtrue
sqlCommandTimeoutTimeout in seconds for SQL session state commands30
stateConnectionStringConnection string for StateServer modetcpip=loopbackaddress:42424
sqlConnectionStringConnection string for SQLServer mode(none)

Method 2: Configuring Session Timeout in IIS

The IIS configuration works alongside web.config and can override application-level settings in certain scenarios.

IIS Manager (GUI)

  1. Open IIS Manager (inetmgr).
  2. Select your application or site in the left panel.
  3. Double-click Session State in the Features View.
  4. Under Cookie Settings, configure the timeout value.
  5. Click Apply in the Actions panel.

IIS Application Pool Settings

The application pool idle timeout can cause sessions to be lost even when the session timeout has not been reached. By default, IIS app pools have a 20-minute idle timeout that shuts down the worker process.

To adjust the app pool idle timeout:

  1. Open IIS Manager.
  2. Click Application Pools in the left panel.
  3. Right-click your application pool and select Advanced Settings.
  4. Under Process Model, set Idle Time-out (minutes) to a value equal to or greater than your session timeout.

Via PowerShell (IIS module):

Import-Module WebAdministration

# View current app pool idle timeout
Get-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name processModel.idleTimeout

# Set app pool idle timeout to 60 minutes
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name processModel.idleTimeout -Value "00:60:00"

# Disable idle timeout entirely (value of 0)
Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name processModel.idleTimeout -Value "00:00:00"

IIS Konfiguration via applicationHost.config

For server-wide changes, edit the IIS applicationHost.config:

<!-- Located at: %windir%\System32\inetsrv\config\applicationHost.config -->
<system.applicationHost>
  <applicationPools>
    <add name="MyAppPool" managedRuntimeVersion="v4.0">
      <processModel idleTimeout="01:00:00" />
    </add>
  </applicationPools>
</system.applicationHost>

Method 3: Programmatic Session Konfiguration

You can control session behavior directly in your C# code.

Setting Timeout in Global.asax

// Global.asax.cs
protected void Session_Start(object sender, EventArgs e)
{
    // Set session timeout to 45 minutes for this session
    Session.Timeout = 45;
}

Setting Timeout Per User Role

// Set different timeouts based on user role
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null)
    {
        if (User.IsInRole("Administrator"))
        {
            Session.Timeout = 60; // Admins get 60 minutes
        }
        else if (User.IsInRole("DataEntry"))
        {
            Session.Timeout = 120; // Data entry users get 2 hours
        }
        else
        {
            Session.Timeout = 20; // Standard users get 20 minutes
        }
    }
}

Setting Timeout in a Controller or Page

// In an ASP.NET MVC Controller
public ActionResult Login(LoginModel model)
{
    if (ModelState.IsValid && ValidateUser(model))
    {
        // Set session timeout after successful login
        Session.Timeout = 30;
        Session["UserName"] = model.Username;
        Session["LoginTime"] = DateTime.UtcNow;
        return RedirectToAction("Dashboard");
    }
    return View(model);
}

// In an ASP.NET Web Forms Page
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // Check remaining session time
        int timeoutMinutes = Session.Timeout;
        Response.Write($"Session timeout: {timeoutMinutes} minutes");
    }
}

Explicitly Abandoning a Session

// End the session immediately (e.g., on logout)
public ActionResult Logout()
{
    Session.Abandon();

    // Also clear the session cookie
    if (Request.Cookies["ASP.NET_SessionId"] != null)
    {
        Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddDays(-1);
    }

    return RedirectToAction("Login");
}

Session State Modes

ASP.NET supports multiple session state storage modes. The choice of mode significantly affects performance, reliability, and timeout behavior.

InProc (In-Process)

<sessionState mode="InProc" timeout="30" />
  • Storage: Server memory (IIS worker process).
  • Leistung: Fastest. No serialization required.
  • Durability: Volatile. Lost on app pool recycle, IIS restart, or server reboot.
  • Scalability: Single server only. Not suitable for web farms or load-balanced environments.
  • Best For: Small applications on a single server.

StateServer (Out-of-Process)

<sessionState mode="StateServer"
    stateConnectionString="tcpip=192.168.1.100:42424"
    timeout="30" />
  • Storage: Separate Windows service (ASP.NET State Service).
  • Leistung: Slower than InProc due to serialization and network overhead.
  • Durability: Survives app pool recycles but lost on service or server restart.
  • Scalability: Can be shared across multiple web servers.
  • Requirement: All session objects must be serializable ([Serializable] attribute).
  • Best For: Web farms that need shared session state without a database.

Enable the State Service:

# Start the ASP.NET State Service
Set-Service -Name aspnet_state -StartupType Automatic
Start-Service -Name aspnet_state

SQLServer

<sessionState mode="SQLServer"
    sqlConnectionString="data source=SQLServer01;Integrated Security=SSPI"
    timeout="30"
    sqlCommandTimeout="30" />
  • Storage: SQL Server database.
  • Leistung: Slowest due to database round-trips.
  • Durability: Fully persistent. Survives all restarts.
  • Scalability: Excellent. Supports large web farms.
  • Requirement: All session objects must be serializable. SQL Server session database must be configured.
  • Best For: Enterprise applications, web farms, high-availability environments.

Setting up the SQL Server session database:

# Run the ASP.NET SQL Server registration tool
aspnet_regsql.exe -S SQLServer01 -E -ssadd -sstype p

The -sstype parameter options:

ValueDescription
tTemporary database (tempdb). Lost on SQL restart.
pPersistent database (ASPState). Survives SQL restart.
cCustom database name specified with -d parameter.

Custom Session State Provider

<sessionState mode="Custom" customProvider="RedisSessionProvider" timeout="30">
  <providers>
    <add name="RedisSessionProvider"
         type="Microsoft.Web.Redis.RedisSessionStateProvider"
         host="localhost"
         port="6379"
         accessKey=""
         ssl="false" />
  </providers>
</sessionState>

Custom providers allow you to use Redis, MongoDB, DynamoDB, or any other backing store.

Sliding vs Absolute Expiration

Sliding Expiration (Default)

ASP.NET uses sliding expiration by default. The session timeout resets with every request. If the timeout is 30 minutes and the user makes a request at minute 29, the session is extended for another 30 minutes.

This is the built-in behavior and does not require any additional configuration.

Implementing Absolute Expiration

ASP.NET does not natively support absolute session expiration, but you can implement it:

// Global.asax.cs - Implement absolute session expiration
protected void Session_Start(object sender, EventArgs e)
{
    Session["AbsoluteExpiry"] = DateTime.UtcNow.AddHours(8);
}

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null &&
        Session["AbsoluteExpiry"] != null)
    {
        DateTime expiryTime = (DateTime)Session["AbsoluteExpiry"];
        if (DateTime.UtcNow > expiryTime)
        {
            Session.Abandon();
            Response.Redirect("~/SessionExpired.aspx");
        }
    }
}

Hybrid Approach (Sliding with Maximum Lifetime)

// Combine sliding expiration with an absolute maximum
protected void Session_Start(object sender, EventArgs e)
{
    Session.Timeout = 30; // 30-minute sliding window
    Session["MaxSessionLifetime"] = DateTime.UtcNow.AddHours(12); // 12-hour hard limit
}

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if (HttpContext.Current.Session != null &&
        Session["MaxSessionLifetime"] != null)
    {
        DateTime maxLifetime = (DateTime)Session["MaxSessionLifetime"];
        if (DateTime.UtcNow > maxLifetime)
        {
            Session.Clear();
            Session.Abandon();
            Response.Redirect("~/Login.aspx?reason=maxlifetime");
        }
    }
}

ASP.NET Core Session Konfiguration

For applications using ASP.NET Core, session configuration is done differently through the middleware pipeline.

Startup.cs / Program.cs Konfiguration

// Program.cs (ASP.NET Core 6+)
var builder = WebApplication.CreateBuilder(args);

// Add session services
builder.Services.AddDistributedMemoryCache(); // Use in-memory cache for development
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
    options.Cookie.Name = ".MyApp.Session";
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});

var app = builder.Build();

// Add session middleware (must be after routing and before endpoints)
app.UseSession();

app.MapControllers();
app.Run();

Using Redis for Distributed Sessions in ASP.NET Core

// Program.cs
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "MyApp_";
});

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

Using SQL Server for Distributed Sessions in ASP.NET Core

// Program.cs
builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("SessionDb");
    options.SchemaName = "dbo";
    options.TableName = "Sessions";
    options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30);
});

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
});

Create the SQL Server cache table:

dotnet sql-cache create "Server=.;Database=MyAppDb;Trusted_Connection=True;" dbo Sessions

Fehlerbehebung Session Timeout Issues

Sessions Expiring Prematurely

Common causes and solutions:

  1. App Pool Recycling: The IIS app pool recycles by default every 1740 minutes (29 hours) or when idle for 20 minutes. InProc sessions are destroyed on recycle.

    • Fix: Increase the idle timeout, use StateServer or SQLServer mode, or disable recycling for the app pool.
  2. Antivirus Scanning: Some antivirus software scans the ASP.NET temporary files folder, causing app domain restarts.

    • Fix: Exclude the ASP.NET temp folder from antivirus scanning: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\
  3. Web.config or Bin Changes: Any modification to web.config or files in the bin folder triggers an automatic app domain restart.

    • Fix: Avoid writing to these directories at runtime.
  4. Memory Pressure: Under high memory conditions, the .NET garbage collector may aggressively collect InProc session data.

    • Fix: Monitor memory usage and consider switching to out-of-process session storage.

Debugging Session State

// Log session events in Global.asax
protected void Session_Start(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine(
        $"Session Started: ID={Session.SessionID}, Time={DateTime.UtcNow}");
}

protected void Session_End(object sender, EventArgs e)
{
    // Note: Session_End only fires for InProc mode
    System.Diagnostics.Debug.WriteLine(
        $"Session Ended: ID={Session.SessionID}, Time={DateTime.UtcNow}");
}

Zusammenfassung

ASP.NET session timeout can be configured through web.config (the sessionState element), IIS Manager settings, or programmatically in C# code. The default timeout is 20 minutes with sliding expiration. Choose the appropriate session state mode based on your application requirements: InProc for single-server simplicity and speed, StateServer for multi-server environments without database overhead, or SQLServer for full persistence and web farm scalability. Always ensure the IIS application pool idle timeout is equal to or greater than your session timeout to prevent premature session loss.

Verwandte Artikel