Archiv für den Monat Juli 2011

MVC 3 und Anwendungsfehler in der Global.asax “auswerten”


Für die Auswertung von Fehlern gibt es die unterschiedlichsten Strategien, ich habe nur nach einer Möglichkeit gesucht, das ich auf meine Benutzerdefinierte Fehlerseite verweisen kann, wenn irgendwo in meiner Webanwendung ein Fehler auftritt und aus dem “alten” ASP.NET kannte ich noch aus der Global.asax die Funktion “Application_Error”, die es in der Global.asax von ASP.NET MVC erst einmal nicht gibt.

Die Funktion kann aber einfach wieder angelegt werden in der global.asax in ASP.NET MVC und dann werden alle Fehler die auftreten und nicht abgefangen werden wieder an diese Funktion “umgeleitet”.

image

In der Funktion selbst kann man dann einfach mit “Context.RewritePath” auf den passenden Controller und View umleiten, den man anlegen muss und dann wird der View angezeigt der hier übergeben wurde.

Dabei kann es sich dann um die eigene Fehlerseite handeln die angezeigt werden soll.

Coole Seite für Extension Methoden


Habe die Tage eine Coole Seite entdeckt, auf der die unterschiedlichsten Extension Methoden aufgelistet sind.

http://www.extensionmethod.net

aufmerksam geworden bin ich auf die Seite als ich eine Extension Methode für Listen gesucht habe um diese nach einem Bestimmten Wert zu sortieren, der z.B. bei MVC in der URL übergeben werden kann und für alle Objekttypen gültig ist. Mit Hilfe einer generischen Extension und Reflections war das dann alles kein Problem mehr.

http://www.extensionmethod.net/Details.aspx?ID=124

Erstellen von URL-String in MVC in externen Codeklassen


Wenn man ein wenig mit MVC gearbeitet hat, stößt man recht schnell auf das Problem, das man z.B. Helper Extensions schreibt und dann gerne auf Funktionen aus dem Controller zugreifen möchte oder aus dem View mit dem man ganz einfach URLs erstellen kann wie “HTML.ActionLink”.

Die erste Hürde die man hier hat, ist das Erstellen des passenden Links, dies ist aber mit Hilfe von”UrlHelper” eine einfache Aufgabe, denn wie man im Quelltext erkennen kann, hat man hier die Funktion “Action” zur Verfügung, die einem Anhand des aktuellen RequestContext einen passenden String für die Url zurück gibt. Der muss dann nur noch mittels eines einfachen String.Format in ein “<a href” eingefügt werden und schon hat man einen eigenen Link erstellt.

image

Messages in MVC zwischen Views bzw. Controllern “übergeben/anzeigen”


Zum übermitteln von Nachrichten zwischen den Views gibt es die unterschiedlichsten Möglichkeiten, man könnte z.B. die Meldungen auch in der URL übergeben, was den Nachteil hat, die URL sieht “unsauber” aus und der Fehler kann evtl. mehrfach angezeigt werden. Denn mit den Methoden die bereits in MVC bereitgestellt werden “ModelState.AddModelError” lassen sich nur Fehler auf dem aktuellen View und Controller ausgeben, sobald man eine Fehlermeldung auf einer anderen Seite ausgeben möchte, ist dies nicht mit “Bordmitteln” von MVC möglich.

Daher habe ich mich für das Abspeichern der Nachrichten im Controller TempData entschieden, da diese Daten nach dem ersten Abrufen wieder aus TempData gelöscht werden. Dazu muss man einmal eine Klasse erstellen auf die man im Controller zugreift und am besten noch einen HTML-Helper der einem die Nachricht dann ganz einfach im View ausgibt.

Außerdem wollte ich gerne unterschiedliche Nachrichtentypen haben, und nicht nur Fehler ausgeben, denn es gibt ja z.B. auch noch Bestätigungen das das Speichern erfolgreich war oder Warnungen.

Als erstes erstellen wie eine Nachrichtenklasse:

image

Die wir später als Grundlage für die Nachricht nehmen die wir übermitteln wollen und dann benötigen wir noch eine Klasse für die Logik, damit wir die Nachrichten so einfach wie möglich unserem TempData hinzufügen können. Am besten mit einem Singleton Pattern, damit wir weniger schreiben müssen beim Hinzufügen der Message.

Im Folgenden also die Logikklasse, welche im Konstruktor den aktuellen Controller benötigt, damit auf TempData zugegriffen werden kann und die Message abgelegt wird.

image

(Leider habe ich bisher noch keine andere Lösung gefunden wie man evtl. noch auf TempData zugreifen kann ohne den Controller übergeben zu müssen, denn dann wäre der Aufruf noch kürzer, über Hinweise freue ich mich sehr!)

Hinzufügen einer Message in Controller oder einer anderen Klasse, hier muss nur jeweils der aktuelle Controller mit übergeben werden.

image

image

Die Anzeige der Fehlermeldung ist, dann ganz Einfach über eine HTML-Helper Extension gelöst und kann in jedem View zum Einsatz kommen, dabei spielt es keine Rolle in welchem Controller oder View die Meldung hinzugefügt wurde.

image

Es müssen dann natürlich noch für die jeweiligen MessageTypes die passenden Css Klassen angelegt werden, damit die Messages auch in der passenden Farbe angezeigt werden können.

Im View reicht es dann einfach nur an der passenden Stelle wo der Fehler angezeigt werden soll den Helper aufzurufen und schon funktioniert das ganze einwandfrei:

image

MVC3 Dynamic Datentyp in Controller zur Linkerstellung benutzen


Ich habe beim Erstellen von MVC Anwendungen gemerkt. das ich zumindest im Controller häufig z.B. RedirectToRoute verwendet habe und hier oftmals die gleichen Parameter übergebe im Dynamischen Teil des Aufrufs mit “new { … }”, das habe ich dann in eine zusätzliche Funktion ausgelagert.

image

die dann einfach den passenden Dynamic Typ zurück gibt.

image

fand ich sehr hilfreich, da ich diesen Aufruf mehrmals verwende in unterschiedlichen Controllerfunktionen und ich dann nicht jedes mal alle Parameter neu schreiben muss und außerdem lässt dich der Link bei Änderungen schneller anpassen, da nur eine Stelle angepasst werden muss.

Funktioniert leider nicht in den Views da in der HTML-Helper Klasse keine Dynamischen Datentypen übergeben werden können soweit ich weiß.

Entity Framework – “OrderBy” Einträge sortiert ausgeben


Wir haben eine einfache Klasse im EF angelegt und wollen direkt im foreach das passende Set durchgehen und nach einer Spalte sortieren, hier ist die Methode “OrderBy” genau richtig.

image

Bei der Verwendung muss aber noch darauf geachtet werden, das nicht einfach nur der Name des Properties nach dem Sortiert werden soll, als String angegeben werden kann. Im “OrderBy”, muss noch auf den Aktuellen Abfragekontext zurückgegriffen werden muss, dieser ist standardmäßig auf “it” eingestellt. Wenn wir also unser “CategorySet” nach der “SortId” sortieren wollen, dann sieht das z.B. folgendermaßen aus.

image

Es kann als alternative Sortiermethode zu “ASC” auch “DESC” angegeben werden.

Weitere Infos findet Ihr auch unter:

http://msdn.microsoft.com/en-us/library/bb896238.aspx

MVC 3 und Benutzerdefinierte Überprüfung der Eingaben mit dem “ValidationAttribute”


Unter ASP.NET MVC 3 ist es sehr einfach sich ein eigenes Validation Attribut zu erstellen, welches dann im Model verwendet werden kann. Ich wollte zum Beispiel prüfen ob ein User Bereits existiert beim Anlegen eines neuen Users.

image

Mit Hilfe meines eigenen Attributes “CheckUserExistsAttribute”, dazu einfach eine neue Klasse anlegen und diese von “ValidationAttribute” ableiten und die Funktion “IsValid” überschreiben.

image

 

Damit ist man schon fertig, wenn man jetzt z.B. auf einer Webseite schon ein Required Attribut verwendet bei einem anderen Property, dann wundert man sich warum das eigene Benutzerdefinierte Attribut nicht “geprüft” wird, in meinem Falle existierte “jr@gmx.de” bereits, wurde aber nicht angezeigt über mein Attribut.

image

Das hat den Hintergrund, das für die bereits implementierten Attribute automatisch die die Validierung per JavaScript eingestellt ist (bei MVC 3) in der web.config und mein Benutzerdefiniertes Attribut keine solche Implementierung beinhaltet und erst auf dem Server ausgewertet wird bei einem kompletten Postback.

image

Die Einbindung von Remote Validation bzw. der zusätzlichen Validierung unter der Hilfe von Javascript kann man auch hier finden:

http://highoncoding.com/Articles/767_Remote_Validation_in_ASP_NET_MVC_3.aspx

http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html

bzw. in dem folgenden Blogpost