<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Tobias</title><link href="http://world.optimizely.com" /><updated>2020-08-25T06:10:59.0000000Z</updated><id>https://world.optimizely.com/blogs/tobias/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Using the ASP.Net Async SessionState Module together with Episerver Visitor Groups</title><link href="https://world.optimizely.com/blogs/tobias/dates/2020/8/using-the-asp-net-async-sessionstate-module-together-with-episerver-visitor-groups/" /><id>&lt;p&gt;The&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://devblogs.microsoft.com/aspnet/introducing-the-asp-net-async-sessionstate-module/&quot;&gt;ASP.Net Async SessionState Module&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;has several benefits over the older default one as it is fully async.&lt;/p&gt;
&lt;p&gt;To use it in an Episerver site is mostly plug and play, just follow the instructions on Microsoft dev blog and your are good to go. There is one scenario I have found were it doesn&#39;t work and that is with Visitor Group criterias that use the session as a storage of state. When registering the session-based criterias they look for the default session state module and if it cannot find it, the criterias will not work. One of these criteras is Landing URL / starting URL, which is used for determining what page on the site the user first visited.&lt;/p&gt;
&lt;p&gt;In order to support the Async module we will have to basically redo what Episerver has done, but switch out the default module for the Async module.&lt;/p&gt;
&lt;p&gt;First we create a&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;IInitializationHttpModule&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and in it we initialize our own State storage handler, as Episervers&#39;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;VisitorGroupStateStorageHandler&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;only works for the default session stage module.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;/// &amp;lt;remark&amp;gt; Taken from Epis VisitorGroupHttpInitialization, to support SessionStateModuleAsync &amp;lt;/remark&amp;gt;
[InitializableModule]
public class AsyncVisitorGroupHttpHandler : IInitializableHttpModule
{
    private AsyncVisitorGroupStateStorageHandler _storageHandler;

    public void Initialize(InitializationEngine context)
    {
    }

    public void Uninitialize(InitializationEngine context)
    {
    }

    public void InitializeHttpEvents(HttpApplication application)
    {
        Create().Initialize(application.Modules, CriterionEvents.Instance);
    }

    private AsyncVisitorGroupStateStorageHandler Create()
    {
        if (_storageHandler == null)
        {
            _storageHandler = new AsyncVisitorGroupStateStorageHandler();
        }

        return _storageHandler;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Now we create or state storage handler. Here the important part is that we go through all modules registered and find the&amp;nbsp;&lt;/span&gt;&lt;code&gt;SessionStateModuleAsync&lt;/code&gt;&lt;span&gt;&amp;nbsp;module so we can hook into session start event. The Visitor group criteria will listen to this, among other events, and for example store the landing URL of the user.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;/// &amp;lt;remark&amp;gt; This is taken from Epis own implementation of VisitorGroupStateStorageHandler, but made to support SessionStateModuleAsync &amp;lt;/remark&amp;gt;
public class AsyncVisitorGroupStateStorageHandler
{
    static ILogger _log = LogManager.GetLogger(typeof(AsyncVisitorGroupStateStorageHandler));
    public void Initialize(HttpModuleCollection application, ICriterionEventsRaiser instance)
    {
        var sessionModule = (SessionStateModuleAsync) application.AllKeys.Select(k =&amp;gt; application[k])
            .SingleOrDefault(module =&amp;gt;
                module is SessionStateModuleAsync);
        if (sessionModule != null)
        {
            sessionModule.Start += (sender, args) =&amp;gt;
            {
                instance.RaiseStartSession(sender,
                    new CriterionEventArgs(new HttpContextWrapper(HttpContext.Current)));
            };
        }
        else
        {
            _log.Warning(&quot;No SessionStateModuleAsync found, criterias relying on session state will not work&quot;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;With this code in place we should now see our visitor groups working as intended.&lt;/span&gt;&lt;/p&gt;</id><updated>2020-08-25T06:10:59.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>