T4MVC Toolkit

8. Dezember 2009

Ich habe endlich die Zeit gefunden, mir erste Videos von der PDC 09 anzuschauen. Angefangen habe ich mit “ASP.NET MVC 2: Ninjas Still on Fire Black Belt Tips” von Scott Hanselman.
Scott zeigt in dieser Präsentation einige Neuerungen in der kommenden Version 2 des MVC Frameworks, sowie auch ein paar ziemlich coole Dinge, welche einem die Entwicklung wirklich erleichtern.
Eine wahre Perle, die ich bisher nicht gekannt habe, und die von nun an fester Bestandteil eines jeden MVC Projektes sein wird, ist das T4MVC Toolkit.
Dass die in Visual Studio eingebaute T4 Engine ziemlich mächtig ist, war mir schon bewusst (Einführung hier), schliesslich verwende ich ja auch eigene Templates in den MVC Projekten (dies wird im Video auch gezeigt).

T4MVC geht aber noch viel weiter. Durch ein simples Kopieren zweier .tt Dateien ins Projekt stehen einem eine stattliche Anzahl stark typisierter Helper Klassen zur Verfügung, welche sich selber automatisch bei jedem Build aktualisieren.

So wird aus

<% Html.RenderPartial("UserControlName"); %>

die typisierte Variante

<% Html.RenderPartial(MVC.ProjektName.Views.UserControlName); %>

Nebst allen Views ist dasselbe verfügbar für alle Controller Actions und es werden Klassen für stark typisierte Links zu Script Files und statischen Ressourcen erzeugt.

Aus

<img src="/Content/bild.jpg" />

wird also

<img src="<%= Links.Content.bild_jpg %>" />

Die kommende Version 5 von Resharper wird einige praktische Refactorings für MVC an Bord haben, welche auch “Magic Strings” in Action Links und dergleichen berücksichtigt, besser ist es jedoch, solche potentielle Baustellen gar nicht erst entstehen zu lassen. T4MVC hilft einem dabei.

ASP.NET MVC Bücher

1. Dezember 2009

ASP.NET MVC in ActionMein bei Manning bestelltes Buch ist nach langer Wartezeit endlich auch in Papierform eingetroffen. ASP.NET MVC in Action ist meiner Meinung nach das zurzeit beste Buch zu diesem Thema. Auf knapp 400 Seiten wird alles Wesentliche zum MVC Framework beleuchtet.
Dabei werden nicht nur einfach alle zu einem typischen MVC Projekt gehörenden Komponenten vorgestellt (sofern es soetwas überhaupt gibt). Die Autoren, welche sich unter anderem auch für das MvcContrib Projekt verantwortlich zeichnen, legen vor allem auch Wert auf die Modell- und Test-getriebene Entwicklung (DDD / TDD).
Besonders gut gefallen haben mir auch die Best Practices Kapitel am Ende, sowie einige Hinweise zum Projekt Aufbau und der Architektur mit NHibernate.
Erfreulich ist auch, dass Manning das Buch nachträglich auch in Formaten für eBook Reader anbietet.

Pro ASP.NET MVC FrameworkMeine zweite Empfehlung, um sich in das Thema einzuarbeiten, ist Pro ASP.NET MVC Framework von Steve Sanderson, dem Autor von xVal.
Im ersten Teil werden anhand eines Beispielprojekts alle relevanten Komponenten des ASP.NET MVC Frameworks vorgestellt. Im zweiten Buchteil werden das Routing, Controller, Views und die Dateneingabe im Detail erklärt. Gerade die Eingabe und die Verarbeitung von Daten aus Formularen benötigt besondere Beachtung, das im Vergleich zu regulären ASP.NET Projekten einiges anders gelöst wird.

Microsoft Ajax Minifier

12. November 2009

Bislang habe ich immer Packer von SmallSharpTools verwendet, um JavaScript Files für die Produktionsumgebung zu verkleinern und ggf. zu komprimieren.

Microsoft hat nun mit einer neuen Version ihrer Microsoft Ajax Library (ehemals ASP.NET AJAX) auch ein neues freies Programm, den Microsoft Ajax Minifier verfügbar gemacht. Anders als es der Name vermuten lässt, können damit jegliche JavaScript Files “minified” werden.

Ich habe es gleich im “Hypercrunch” Modus am Beispiel des jQuery Plugins für das Grid von etcetera.Mvc ausprobiert. und das Resultat hat mich überzeugt:

  • jquery-etcetera.js Entwicklerversion: 6′618 Bytes – 100%
  • jquery-etcetera.min.js mit Packer: 3′521 Bytes – 53%
  • jquery-etcetera.min.js mit Ajax Minifier: 2852 Bytes – 43%

Die geringere Grösse resultiert vor allem durch das Umbenennen von lokalen Variablen.
Das gute am neuen Tool ist, dass es auch einen MSBuild Task mitbringt, somit also ideal in den Build Prozess integriert werden kann.

Neue UI Komponente GoogleMaps für ASP.NET MVC

11. November 2009

Ich habe eine neue HTML Helper Komponente in meine Library etcetera.Mvc aufgenommen. Die macht es möglich, mit wenigen Zeilen im View die bekannten Google Maps auf der Seite darzustellen:

Google Maps

Der Html Helper unterstützt alle Steuerelemente, welche Google in ihrem API anbietet. Das obenstehende Beispiel wurde mit folgendem Aufruf erzeugt:

<%= Html.GoogleMap()
        .Width(640)
        .Height(480)
        .ApiKey("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
        .Language(MapLanguage.de)
        .Coordinates("47.1,8.1")
        .ZoomLevel(8)
        .ScrollZoom()
        .EnableMapType(MapType.Map)
        .EnableOverviewMap()
        .ZoomControlType(MapZoomControlType.LargeMapControl3D)
        .ScrollZoom()
        .Markers(new List<Marker>
                     {
                       new Marker("47.1, 8.1", "I'm a test bubble."),
                       new Marker("47.2, 8.2", "I can describe <strong>interesting</strong> <br />places using HTML.", true)
                     })
 %>

Die Komponente steht vorerst nur via Source Code zur Verfügung, ein Release folgt bald.

Einer fürs Wochenende

30. Oktober 2009

Heute via Mail erhalten:

dbjoke

In diesem Sinne wünsche ich ein schönes Wochenende!

Routing mit ASP.NET WebForms, Teil 2

29. Oktober 2009

In Teil 1 ging es darum, wie die ASP.NET 3.5 Routing Engine in einer WebForms Applikation genutzt werden kann. Angeschaut wurde die Konfiguration der Applikation für die Engine, und das Definieren und Auswerten eigener Routen.
In diesem zweiten Teil werden nun die Security Aspekte angeschaut.

Das Routing Modul verarbeitet die Events in der Request Pipeline nachdem die Authentisierung und Autorisierung bereits stattgefunden hat. Das bedeutet, dass die Benutzer anhand der sichtbaren URL autorisiert werden und nicht über den virtuellen Pfad zum WebForm.

Wenn also der Zugriff auf unsere Beispiel URL “customer/” nur authentisierten Benutzern gestattet sein soll, kann dies über einen Eintrag im Root web.config erreicht werden:

<location path="customer">
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</location>

Anonyme Benutzer der Applikation können nun nicht mehr auf Adressen wie “customer” oder “customer/42″ zugreifen, sondern werden auf eine Login Seite umgeleitet. Diese enthält sogar den Pfad unserer Route:

Login mit Return URL

Login mit Return URL

Nun muss noch sichergestellt werden, dass die Authorisation Prüfung über den virtuellen Pfad erfolgt, den der RouteHandler verwendet. Die Methode GetHttpHandler sieht also wie folgt aus:

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
    if (!UrlAuthorizationModule.CheckUrlAccessForPrincipal(_virtualPath, requestContext.HttpContext.User, requestContext.HttpContext.Request.HttpMethod))
    {
        requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        requestContext.HttpContext.Response.End();
    }

    var page = BuildManager.CreateInstanceFromVirtualPath(_virtualPath, typeof(Page));

    var queryString = new StringBuilder("?");
    foreach (var rdv in requestContext.RouteData.Values)
    {
        queryString.Append(requestContext.HttpContext.Server.UrlEncode(rdv.Key));
        queryString.Append("=");
        queryString.Append(requestContext.HttpContext.Server.UrlEncode(rdv.Value.ToString()));
        queryString.Append("&");
    }
    queryString.Remove(queryString.Length - 1, 1);

    HttpContext.Current.RewritePath(string.Concat(_virtualPath, queryString));

    return (IHttpHandler)page;
}

Eine letzte Einstellung ist noch nötig. Anonyme Benutzer können immer noch direkt über den physikalischen Pfad (z.B. ~/Customers/CustomerDetail.aspx) auf die WebForms zugreifen. Dies kann verhindert werden, indem eine web.config Datei im entsprechenden Verzeichnis angelegt wird:

<configuration>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</configuration>

Ich habe ein Beispielprojekt zusammengestellt, welches alle besprochenen Elemente zeigt: RoutingWebApplication.zip