// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= ASP.NET Session State Caching

== Overview

The ASP.NET session state caching is designed to allow you to store user session data in different sources.
By default, session state values and information are stored in memory within the ASP.NET process.

Ignite.NET implements a session state store provider that stores session data in a distributed Ignite cluster that spreads
the session data across multiple servers in order to provide high availability, load balancing and fault tolerance.

[CAUTION]
====
[discrete]
=== Development and Debugging
During development and debugging, IIS will dynamically detect code changes when you build and run your web application.
This, however, does not restart the embedded Ignite instance and can cause exceptions and undesired behavior.
Make sure to restart IIS manually when using the Ignite Session State Cache.
====

== Installation

* *Binary distribution*: add a reference to Apache.Ignite.AspNet.dll
* *NuGet*: `Install-Package Apache.Ignite.AspNet`

== Configuration

To enable the Ignite-based session state storage, modify the `web.config` file as follows:

[tabs]
--
tab:web.config[]
[source,xml]
----
<system.web>
  ...
  <sessionState mode="Custom" customProvider="IgniteSessionStateProvider">
    <providers>
      <add name="IgniteSessionStateProvider"
           type="Apache.Ignite.AspNet.IgniteSessionStateStoreProvider, Apache.Ignite.AspNet"
           igniteConfigurationSectionName="igniteConfiguration"
           applicationId="myApp"
           gridName="myGrid"
           cacheName="aspNetSessionCache" />
    </providers>
  </sessionState>
  ...
</<system.web>
----
--

While the `name` and `type` attributes are required, the other attributes listed below are optional:

[cols="1,3",opts="header"]
|===
|Attribute |Description
|`igniteConfigurationSectionName`| The `web.config` section name defined in `configSections`. See
link:http://127.0.0.1:4000/docs/net-specific/configuration-options#configure-with-application-or-web-config-files[Configuration: web.config] for
more details. This configuration will be used to start Ignite if it is not started yet.
|`applicationId`| Should only be used when multiple web applications share the same Ignite session state cache. Assign
different ID strings to avoid session data conflicts between applications. It is recommended to use a separate cache
for each application via `cacheName` attribute.
|`gridName`| Session state provider calls `Ignition.TryGetIgnite` with this grid name to check whether Ignite is already started.
|`cacheName`| Session state cache name. Default is `ASPNET_SESSION_STATE`.
|===

For more details on how to start Ignite within an ASP.NET application, refer to link:net-specific/asp-net-output-caching[ASP.NET Output Caching].
Also, see link:net-specific/deployment-options#asp-net-deployment[ASP.NET Deployment] for web deployment specifics related to the `IGNITE_HOME` variable.
