Wie funktioniert ASP.NET-Inline-Code?

Seit den Anfangszeiten von ASP.NET vor vielen Jahren gibt es die Möglichkeit von Inline-Code, also die Möglichkeit, Code-Schnippsel in HTML einzustreuen. Hier ist ein kleines aktuelles Beispiel mit ASP.NET MVC 2, Teil einer Seite mit einer HTML-Tabelle, bei der die Zeilen mit Hilfe einer Schleife gebildet werden, die in C# programmiert ist:

<table>
    <% foreach (var item in Model) { %>
        <tr>
            <td>
                <%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
                <%: Html.ActionLink("Delete", "Delete", new { id=item.Id })%>
            </td>
            <td>
                <%: item.Id %>
            </td>
            <td>
                <%: item.Title %>
            </td>
            <td>
                <%: String.Format("{0:g}", item.DateReleased) %>
            </td>
        </tr>
    <% } %>
</table>

Ich habe mich in der Vergangenheit schon öfters gefragt, wie genau ein solches buntes Gemisch von HTML und Code zur Ausführung kommt. Es wird ja wohl nicht so sein, dass irgendein Prozess den Text durchgeht und dabei jeweils fliegend zwischen einer Art „HTML-Modus“ und einer Art „Code-Modus“ wechselt, also quasi die Mischung nachvollzieht. Aber wie es geht es dann?

Am einfachsten sieht man, was läuft, wenn man auf irgendwelchen Code auf so einer Seite einen Breakpoint setzt und sich dann nach einem Break im Debugger genauer ansieht, wo man denn gelandet ist. Die Seiten einer Website mit Code werden durch dynamische Compilation in eine temporäre .NET-Assembly verwandelt, die typischerweise unter kryptischem Namen in einer kryptischen Directory abgelegt ist, bei mir z.B.

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\d0bb04eb\40bc3df1\App_Web_sm1qknju.dll

Pro Seite gibt es 1 Klasse, und in jeder Klasse ist eine Methode namens __RenderContent2() zuständig dafür, den Inhalt der Seite d.h. das reine HTML zu generieren. Dank dem IL-Disassembler ILDASM kann man sich auf einfache Weise die Details einer solchen Methode ansehen.

Die Lösung, wie genau die Mischung von Code und HTML realisiert wird, ist denkbar einfach und eigentlich wenig überraschend: Es wird alles zu Code. Was schon Code ist, bleibt natürlich Code, und alle verbleibenden Sequenzen von Zeichen vor, zwischen und nach Code-Stücken, die HTML darstellen, werden mit Hilfe von Aufrufen von System.Web.UI.HtmlTextWriter.Write ausgegeben.

Das sieht disassembliert dann z.B. so aus:

IL_0031: ldarg.1
IL_0032: ldstr „\r\n </td>\r\n“
IL_0037: callvirt instance void [mscorlib]System.IO.TextWriter::Write(string)

Nun zu wissen, „wie es geht“, bringt mir nicht unbedingt viel, aber immerhin habe ich jetzt kein schlechtes Gefühl mehr, wenn mir das ständige Abwechseln von kleinen HTML-Stücken und Code-Stücken zu dumm wird und ich dann Dinge schreibe wie:

<% Response.Write("<td>"+item.Id+"</td><td>"+item.Title+"</td><td>"+String.Format("{0:g}", item.DateReleased)+"</td>") %>

Schliesslich entspricht das mehr oder weniger dem, was technisch gesehen zur Ausführung kommt, wenn ich es als „Mischung“ hinschreibe. (Acht geben muss ich dabei allerdings darauf, dass ich den bei <%: automatisch inbegriffenen Aufruf von Server.HtmlEncode bei Bedarf selbst mache; siehe hierzu z.B. diesen Artikel.)

Veröffentlicht in Keine Kategorie. Schlagwörter: , , . Leave a Comment »