automatische Formatierung nach Datentyp

In einer meiner ASP.NET Core Schulungen, kam die Frage auf warum Visual Studio beim Scaffolding eines DB Models DisplayFor nimmt und nicht einfach @Model. Die Antwort darauf ist etwas länger.

Als Scaffolding bezeichnet Microsoft, wenn man anhand eines EF Models automatisch die CRUD Razor Pages erstellen lässt. Also Index.cshtml für Auflistung, Edit.cshtml für Editieren usw. Einsatzzweck ist die typische Geschäftsanwendung (LOB) mit vielen SQL Tabellen.

Diese Funktion gibt es in ASP.NET Webforms schon lange, ist aber kaum bekannt. Im Tandem mit Dynamic Data, wird das aber erst eine Produktivitätswaffe. Je nach verwendeten Datentyp kann in diese Templates das HTML Rendering im Detail definiert werden. Völlig losgelöst von der Ansicht. Wem die Datentypen nicht reichen, definiert abweichende Rendertemplates und weist die über DataAnnotations einem Property des Models zu. Verwendungszweck: Kalender Ansicht für DateTime, Checkbox für Bool, ErrorMessages mit Boostrap designen.

 

Der Ansatz ist in ASP.NET core ganz ähnlich. Zunächst der Sorucecode einer generierten Razor View, die absichtlich in Zeile 5 manuell verändert wurde um die Fragestellung zu verdeutlichen.

   1:   <td>
   2:      @Html.DisplayFor(modelItem => item.OrderDate)
   3:  </td>
   4:  <td>
   5:      @Model.Orders[0].RequiredDate
   6:  </td>
   7:  <td>

Der HTML Helper DisplayFor nimmt sich eine Partial View aus dem DisplayTemplates Verzeichnis um die finale Darstellung korrekt als HTML zu rendern. Diesen Ordner DisplayTemplates (oder auch EditTemplates für den Edit Modus) findet man aber im Visual Studio Projekt nicht. Er ist in ASP.NET hart codiert. Aber man kann diese Formatierungsregeln überschreiben indem man die Verzeichnisse und Razor Dateien einfach per Hand anlegt.

image

Normalerweise sind Partials mit einem _ Präfix versehen. Das ist in diesem Fall unpassend, da der Name direkt auf den Daten Typ verweist (DateTime). Wem dieser Automatismus Model View zu eng ist, der kann auch jedem Property seinen eigene View Renderer mitgeben per Attribut UIHint aus System.ComponentModel.DataAnnotations

   1:  public int? EmployeeId { get; set; }
   2:  public DateTime? OrderDate { get; set; }
   3:  public DateTime? RequiredDate { get; set; }
   4:  [UIHint("Hannes")]
   5:  public DateTime? ShippedDate { get; set; }
   6:  public int? ShipVia { get; set; }

Die Syntax in den Display Templates ist Razor üblich und nimmt den zu formatierenden Datentyp als Model. Hier hannes.cshtml

   1:  @model System.DateTime
   2:  <span style="color:green">
   3:      @Model.ToString("dd.MMM.yyyy")
   4:  </span>

 

Zur Laufzeit sieht der zufriedene Web Browser Nutzer in der Liste das Datums Feld einmal per Datentyp formatiert, unformatiert und per UIHint

image

Wirft man einen Blick in Edit.cshtml sieht man dort die neuere Variante aus Razor, die Tag Helper, statt den HTML Helpern. ASP.NET MVC Entwickler müssen anstatt noch HTML.EditorFor verwenden. In Razor reicht ein elegantes asp-for.

   1:  <div class="form-group">
   2:         <label asp-for="Orders.ShipPostalCode" class="control-label"></label>
   3:         <input asp-for="Orders.ShipPostalCode" class="form-control" />
   4:         <span asp-validation-for="Orders.ShipPostalCode" class="text-danger">

Weitere Versuche in Listen das DisplayFor durch ein asp-for zu ersetzen führten zu keinem zufriedenstellenden Resultat. Außerdem suche ich noch den Source Code der default HTML Renderer oder eine Möglichkeit diese beiden Template Verzeichnisse samt Inhalt anlegen zu lassen. Das macht Webforms ganz automatisch.

Kommentare sind geschlossen