Redirect und Session-Variablen in ASP.NET

In ASP.NET  gibt es ein hässliches kleines Problem, man könnte es auch als Bug bezeichnen: Werden gleich zu Beginn einer Session Session-Variablen gesetzt und umittelbar danach ein Redirect aufgerufen, dann gehen die Session-Variablen verloren. Gemäss diversen Artikeln lässt sich dieses Problem umgehen, wenn man den zweiten Parameter von Redirect (endResponse) auf false setzt. Allerdings hat das in meinem Fall mit einer ASP.NET-Version 2.0.5 nicht funktioniert, und viele andere Beiträge berichten ähnliches. Das Problem besteht übrigens nur beim allerersten Aufruf, wenn die Session noch nicht existiert, sobald einmal eine Session-ID als Cookie gespeichert ist, tritt das Phänomen nicht mehr auf.

Meine Aufgabenstellung bestand darin, einen Request von einem externen Server je nach einer bestimmten Konstellation von Parametern an meine internen Seiten weiterzuleiten. Ich hatte dasselbe in ASP Dutzende von Malen gemacht und war bass erstaunt, als ich es in ASP.NET einfach nicht zum laufen bekam. Der Request kommt von einem fremden Server, so dass ich auf den Aufruf keinen Einfluss hatte und der Webserver ist nicht in meiner Verantwortung, so dass der Patch, der gelegentlich gegen diesen Bug empfohlen wird, keine Option war.

Die einzige funktionierende Lösung für meinen Fall ist ein Trick: Da das Problem nur zu Beginn einer Session besteht, habe ich eine ASP.NET-Seite vorgeschaltet, die nichts anderes macht als die Session erzeugen (indem eine Session-Variable gesetzt wird) und dann auf die Seite mit der eigentlichen Verarbeitung weiterzuleiten. Der Trick besteht nun darin, dass der Redirect nicht in ASP.NET erfolgt, sondern in einem HTML-Metatag. Und dieses Metatag ist natürlich nicht statisch, denn dann könnte es ja die ankommenden Parameter nicht weitergeben, sondern es wird im ASP.NET Code erzeugt.

Der HTML-Teil der Seite sieht folgendermassen aus:

<%@ Page Language="C#" AutoEventWireup="true"
  CodeFile="Start.aspx.cs" Inherits="Start" %>
<!DOCTYPE html PUBLIC
  "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head runat="server">
    <%= metatag %>
     <title></title>
  </head>
  <body>
  </body>
</html>

Der einzig wichtige Teil davon ist <%= metatag %>. Im Code-Behind wird diese Variable dann mit dem konkreten Wert gefüllt:

public partial class Start : System.Web.UI.Page {
   public String metatag = null;
   protected void Page_Load(object sender, EventArgs e) {
     Session["started"] = "y";
     metatag = "<meta HTTP-EQUIV=\"REFRESH\" 
       content=\"0; url=MyPage.aspx?"
       + Request.QueryString + "\">";
   }
}

Als erstes setzt man eine Session-Variable. Name und zugewiesener Wert sind völlig bedeutungslos, sie wird nur benötigt, damit die Session erzeugt wird. Die zweite Anweisung erzeugt ein HTML-Tag zur Weiterleitung und gibt diesem die mit Request.Querystring entgegengenommenen Parameter mit. Erst die aufgerufene Seite MyPage.aspx macht dann die vorgesehene Verarbeitung der Parameter und die eigentliche Weiterleitung aufgrund der Parameterkonstellation. Da auf dieser Seite nun bereits eine Session existiert, kann man Session-Variablen setzen und anschliessend ein ganz normales Response.Redirect machen.

Comments are closed.