Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Benutzung des Substitution Controls um die Ausgabe zu cachen

ASP.NET hat viele Möglichkeiten um Ausgaben oder Daten zu cachen, unter anderem gibt es ein Control mit dem Namen "Substitution" - auf der Zunge vergeht der Name nicht, der Nutzen des Controls ist allerdings nicht zu unterschätzen.

Unter folgendem Link (Übersicht über das Substitution-Webserversteuerelement) findet ihr eine gute Übersicht vom Control.

Wenn es darum geht Daten zu cachen, dann meist weil es lange geht, diese abzurufen, oder aber die Zugriffe immens sind.
Dies kann beispielsweise einen WebRequest auf eine Url sein, die gar nicht erreichbar sein _muss_, oder eine Abfrage ans Dateisystem um Dateiinhalte anzuzeigen, die ggf. aktualisiert worden sind.

Zu beiden Aufgabenstellungen möchte ich hier jeweils ein Beispiel liefern.

Um das erste Beispiel ermöglichen zu können brauchen wir im App_Data-Verzeichnis eine Textdatei mit dem Inhalt "Hallo Welt", diese wollen wir später abfragen.
Danach braucht es ein Substitution-Control auf der ASPX-Seite, soweit wäre das schon fast alles.

Der ASPX-Teil sieht dann ungefähr so aus:

<h1>Substitution-Control Beispiel</h1>
<fieldset>
    <legend>Dateiinhalt</legend>
    <asp:Substitution ID="subFile" runat="server" />
</fieldset>
<fieldset>
    <legend>Teil aus einem WebRequest</legend>
    <asp:Substitution ID="subWebRequest" runat="server" />
</fieldset>

Das Control hat eine einzige wichtige Eigenschaft: "MethodName".
Der hier angegebene Methodennamen wird dazu benutzt, die Methode - falls vorhanden - aufzurufen.

Dabei liefert die Methode den Inhalt des Controls (Als literalen Content) als String zurück.
Dieser wird danach anstelle des Substitution-Control Markups angezeigt, er wird je nach Logik aus dem Cache geladen oder frisch aktualisiert.

Die Methode muss statisch sein der nachstehenden Signatur folgen:

protected / public string <Name>(HttpContext context);

 

Über den Parameter vom Typ HttpContext kann unter anderem auf den Cache, Response oder den Request zugegriffen werden.
Zuerst müssen wir einen Methodennamen zuweisen, beispielsweise so im Codebehind:

subFile.MethodName = "subFile_GetData";

Folgend die Implementation um den Inhalt einer Datei entweder aus dem Cache auszulesen oder aber aktuell zu holen.
Das kann einfach über eine CacheDependency gelöst werden.

CacheDependencys (Es gibt auch eine SqlCacheDependency) überprüfen die Gültigkeit des Cache-Inhaltes aufgrund von verschiedenen Eingaben (Dateinamen / Letzte Änderung / Datenbankänderungen, etc...) und setzen den Cache-Inhalt auf "null" / "Nothing" wenn aktuellere Daten verfügbar sind bzw. die Cache-Zeit abgelaufen ist.



protected static string subFile_GetData(HttpContext context) {
    const string subFileKey = "subFileKey";

    object cacheContent = context.Cache[subFileKey];

    if (cacheContent != null) {
        // Inhalt aus dem Cache anzeigen
        return cacheContent.ToString();
    } else {
        // Daten abrufen (Zeitintensiv) und Cache aktualisieren
        string path = context.Request.MapPath("~/App_Data/test.txt");

        if (File.Exists(path)) {
            // --> zeitaufwändige Aktion
            string content = File.ReadAllText(path);
            // <-- Ende

            // Cache mit einer CacheDependency auffüllen
            CacheDependency d = new CacheDependency(path);
            context.Cache.Insert(subFileKey,
                                             content,
                                             d);
            return content;
        } else {
            return String.Empty;
        }
    }
}

Sobald der Inhalt der Textdatei bzw. dessen Änderungsdatum geändert haben, wird der Cache ungültig, ist somit "null" / "Nothing" und der aktuelle Inhalt wird in den Cache eingelesen + angezeigt.

Bei einem WebRequest sieht es ein wenig anders aus, jedoch verfährt es nach dem gleichen Prinzip (Also Cache auf "null" prüfen und ggf. Daten aktualisieren).
Anstelle einer CacheDependency wird eine Zeitdauer eingestellt.
Für diese Dauer ist der Cacheinhalt gültig, nach Ablauf wird - in diesem Fall - ein neuer WebRequest losgeschickt und der Cache wieder gefüllt:



protected static string subWebRequest_GetData(HttpContext context) {
    const string subWebRequestKey = "subWebRequestKey";

    object cacheContent = context.Cache[subWebRequestKey]; 
    if (cacheContent != null) {
        return cacheContent.ToString();
    } else {
        WebClient client = new WebClient();

        try {
            string searchKey = "von ungefähr <b>";
            int resultLength = 10;

            string content = client.DownloadString(new Uri("http://www.google.ch/" +
                                    "search?hl=de&q=asp.net&btnG=Google-Suche&meta="));

            int index = content.IndexOf(searchKey);

            if (index > -1) {
                index += searchKey.Length;
                content = content.Substring(index, resultLength);

                // Cache mit der Gültigkeit von 10 Sekunden eintragen
                context.Cache.Insert(subWebRequestKey,
                                     content,
                                     null,
                                     DateTime.Now.AddSeconds(10),
                                     TimeSpan.Zero
                    );

                return content;
            }
        } catch {
            return String.Empty;
        }
    }
    return String.Empty;
}

Das Substitution-Control stellt nur ein Hilfsmittel dar, um Daten aus dem Cache direkt auf der Webseite anzuzeigen.
Die Vorgehensweise innerhalb der "GetData"-Methoden kann auch an einer anderen Stelle genutzt werden, um Daten aus dem Cache anzuzeigen.

Viel Spass damit.

Download des Beispielprojekts:

MSDN-Links:

Veröffentlicht Sonntag, 3. August 2008 22:21 von Peter Bucher

Kommentare

# re: Benutzung des Substitution Controls um die Ausgabe zu cachen

Hoi Peter,

danke für die kleine Einführung. Ich habe das Control tatsächlich bisher nie weiter beachtet. Es scheint ja doch ganz nützlich zu sein.

Gruß Jürgen

Montag, 4. August 2008 11:29 by Jürgen Gutsch

# re: Benutzung des Substitution Controls um die Ausgabe zu cachen

Hoi Jürgen

Danke für deinen Kommentar.

Es geht vorallem auch um das Caching an sich, das Control ist aber auch nett :)

Montag, 4. August 2008 12:09 by Peter Bucher
Anonyme Kommentare sind nicht zugelassen