Aufgeteiltes Datumsfeld mit ASP.NET MVC Editor Templates

In vielen Projekten gibt es die Anforderung dass der User im Registrierungsformular ein Datum nicht in ein Textfeld eingeben sondern aus 3 Dropdownlisten für Tag, Monat und Jahr auswählen soll. Mit etwas Code und einem eigenen Editor Template für ASP.NET MVC 2 gestaltet sich die Umsetzung sehr einfach und elegant.

Den Anfang machen zwei kleine Hilfklassen: die SplittedDate und die SplittedDateListHelper Klasse. Die erste definiert das Custom Date Format für das aufgeteilte Datum. Auf diese Klasse wird später der Modelbinder die Auswahl der einzelnen Dropdowns mappen.

public class SplittedDate {
	public int Day { get; set; }
	public int Month { get; set; }
	public int Year { get; set; }

	public SplittedDate() : this(DateTime.Now) {}

	public SplittedDate(DateTime birthday)
		: this(birthday.Day, birthday.Month, birthday.Year) {}

	public SplittedDate(int day, int month, int year)	{
		Day = day;
		Month = month;
		Year = year;
	}

	public DateTime AsDateTime() {
		return new DateTime(Year, Month, Day);
	}

	public override string ToString() {
		return new StringBuilder()
                               .Append(Day)
                               .Append(".")
                               .Append(Month)
                               .Append(".")
                               .Append(Year).ToString();
	}
}

Die zweite Klasse ist ein ViewHelper und erzeugt Listen für den Tag (1 -31), den Monat (Januar – Dezember) und das Jahr (100 Jahre). Da die einzelnen Listen bereits SelectListItems enthalten, können sie ganz einfach mit dem MVC eigenen ViewHelper for Dropdowns verwendet werden.

public class SplittedDateListHelper {
	private static IList<SelectListItem> _days;
	private static IList<SelectListItem> _months;
	private static IList<SelectListItem> _years;

	public static IList<SelectListItem> Days {
		get {
			if (_days == null) 	{
				_days = new List<SelectListItem> {
                                    new SelectListItem { Text = "Tag", Value = "-1" }};
				for (var i = 1; i <= 31; i++) {
					_days.Add(new SelectListItem {
                                            Text = i.ToString(), Value = i.ToString()});
				}
			}

			return _days;
		}
	}

	public static IList<SelectListItem> Months {
		get {
			if (_months == null) {
				_months = new List<SelectListItem> {
				    new SelectListItem {Text = "Monat", Value = "-1"},
				    new SelectListItem {Text = "Januar", Value = "1"},
				    new SelectListItem {Text = "Februar", Value = "2"},
				    new SelectListItem {Text = "März", Value = "3"},
				    new SelectListItem {Text = "April", Value = "4"},
				    new SelectListItem {Text = "Mai", Value = "5"},
				    new SelectListItem {Text = "Juni", Value = "6"},
				    new SelectListItem {Text = "Juli", Value = "7"},
				    new SelectListItem {Text = "August", Value = "8"},
				    new SelectListItem {Text = "September", Value = "9"},
				    new SelectListItem {Text = "Oktober", Value = "10"},
				    new SelectListItem {Text = "November", Value = "11"},
				    new SelectListItem {Text = "Dezember", Value = "12"}
			    };
			}

			return _months;
		}
	}

	public static IList<SelectListItem> Years {
		get {
			if (_years == null) {
				_years = new List<SelectListItem> {
                                    new SelectListItem { Text = "Jahr", Value = "-1" } };
				var currentYear = DateTime.Now.Year;

				for (var i = currentYear; i >= currentYear - 100; i--) {
					_years.Add(new SelectListItem { Text = i.ToString(), Value = i.ToString() });
				}
			}

			return _years;
		}
	}
}

Doch wie erhält man nun die 3 gewünschten Dropdown-Listen im Eingabeformular? Hierfür bietet ASP.NET MVC 2 mit den Editor Templates eine einfache und elegante Lösung an. Editor Templates sind im Grunde Partial Views für einen bestimmten Objekttyp und erlauben es dem Entwickler sehr genau festzulegen wie und welche Eingabeelemente (eben der Editor) für den Objekttyp gerendert werden sollen. Eine hervorragende Einführung zu den Templates in ASP.NET MVC 2 gibt Brad Wilson in seinem Blog. Um nun ein Editor Template für die SplittedDate Klasse zu erstellen, wird im Ordner ~/Views/Shared/EditorTemplates eine Partial View namens SplittedDate.ascx mit folgendem Inhalt angelegt:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="TestProject.Web.Mvc.Helper" %>
<p class="splitDate-field">
    <label for="DayOfBirth_Day">
        Tag</label>
    <select id="DayOfBirth_Day" name="DayOfBirth.Day">
        <% foreach (var day in SplittedDateListHelper.Days)
           { %>
        <option value="<%= day.Value %>">
            <%= day.Text %></option>
        <% } %>
    </select>
</p>
<p class="splitDate-field">
    <label for="DayOfBirth_Month">
        Monat</label>
    <select id="DayOfBirth_Month" name="DayOfBirth.Month">
        <% foreach (var month in SplittedDateListHelper.Months)
           { %>
        <option value="<%= month.Value %>">
            <%= month.Text %></option>
        <% } %>
    </select>
</p>
<p class="splitDate-field">
    <label for="DayOfBirth_Year">
        Jahr</label>
    <select id="DayOfBirth_Year" name="DayOfBirth.Year">
        <% foreach (var year in SplittedDateListHelper.Years)
           { %>
        <option value="<%= year.Value %>">
            <%= year.Text %></option>
        <% } %>
    </select>
</p>
<br class="clear">

Der Code im Template ist nichts umwerfend Neues. Man erzeugt lediglich für jedes Property der SplittedDate Klasse eine entsprechende Dropdown Liste, wobei man darauf achten muss im jeweiligen name Attribute des select Tags die richtige Property zu verwenden, da so der Model Binder die Auswahl automatisch auf das entsprechende Objekt im ViewModel mappen kann z.B. für das Jahr <select id=”DayOfBirth_Year” name=”DayOfBirth.Year”>.

Nachdem nun alle Bausteine vorhanden sind, ist es an der Zeit sie zu einem großen Ganzen zusammenzufügen. Angenommen man benötigt das aufgeteilte Datum für die Angabe des Geburtstages in einem Registrierungsformular. So würde man sich zunächst ein ViewModel ähnlich dem folgenden für das Formular bauen.

public class CreateAccountViewModel {
	[Required(ErrorMessage = "Darf nicht leer sein.")]
	public string Alias { get; set; }
	[Required(ErrorMessage = "Darf nicht leer sein.")]
	public string Password { get; set; }
	[Required(ErrorMessage = "Darf nicht leer sein.")]
	public string ConfirmPassword { get; set; }
	[Required, ValidateSplittedDatetime]
	public SplittedDate DayOfBirth { get; set; }
}

Wie man sieht findet hier das neue SplittedDate Objekt Anwendung. Im nächsten Schritt würde man das dazugehörige Formular bauen. (Ich zeige es hier nur auszugsweise]

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TestProject.Web.Mvc.Models.CreateAccountViewModel>" %>
<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="MainContent">
    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm("Create", "Account", FormMethod.Post, new { id = "signup" }))
       { %>
    <fieldset>
        <table>
            <tbody>
                <tr>
                    <th>
                        <label for="Alias">
                            Benutzername</label>
                    </th>
                    <td class="form-field">
                        <%= Html.EditorFor(m => m.Alias) %>
                    </td>
                    <td>
                        <div class="form-hint">
                            <span class="hint-text">Wählen Sie einen Benutzernamen</span>
                            <%= Html.ValidationMessageFor(m => m.Alias) %>
                        </div>
                    </td>
                </tr>                

				...

                <tr>
                    <th>
                        <label for="DayOfBirth">
                            Geburtstag</label>
                    </th>
                    <td class="form-field">
                        <%= Html.EditorFor(m => m.DayOfBirth) %>
                    </td>
                    <td>
                        <div class="form-hint">
                            <span class="hint-text">Ihr Geburtstag</span>
                            <%= Html.ValidationMessageFor(m => m.DayOfBirth) %>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
        <p>
            <input type="submit" id="submitForm" class="formButton white" value="Registieren" />
        </p>
    </fieldset>
</asp:Content>

Und so sieht schlußendlich das Ergebnis aus:
Aufgeteiltes Datumsfeld im Formular

ASP.NET MVC 2 RC2 veröffentlicht

Wie Phil Haack in seinem Blog mitteilt, steht der zweite Release Candidate für ASP.NET MVC 2 zum Download bereit. Auch wenn dieses Release in erster Linie ein Bugfix Release ist, hat das Team die Gelegenheit ergriffen und das kritisierte Standardverhalten der Model Validation geändert. Wurden früher nur diejenigen Properties validiert die zum Server gepostet wurden, werden nun alle Properties des Model validiert unabhängig davon ob neue Werte gesetzt wurden oder nicht. Weiterhin wurde an der Performance Schraube gedreht. Weitere Einzelheiten sind den Release Notes zu entnehmen.

Download ASP.NET MVC 2 RC 2

Git config anpassen

Über die config Datei kann man Git  je Repository seinen Beürfnissen anpassen. Das umfasst z.B. die Festlegung des bevorzugten Merge Tools, das Anpassen von Farben (sinnvoll wenn man mit Git auf der Konsole arbeitet) und die Definition von Abkürzungen für die häufigsten Git Kommandos. Meine bevorzugte Konfiguration sieht so aus:

[merge]
tool = kdiff3
[mergetool "kdiff3"]
path = c:/Program Files/KDiff3/kdiff3.exe
[color]
ui = auto
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan
[color]
ui = true
[color "diff"]
whitespace = red reverse
[alias]
st = status
ci = commit -m
br = branch
co = checkout
df = diff
lg = log -p

Git exclude für Visual Studio Projekte

Die folgenden Einträge in der git exclude Datei sind speziell auf Visual Studio Projekte zugeschnitten und halten das Repository frei von unnötigen Dateien / Verzeichnissen.

Anpassungen exclude Datei:

#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*

Länderliste für ASP.NET – schnell und einfach

Das Erstellen eines Länder-Dropdowns ist zumeist mit viel Handarbeit verbunden (sofern man sie nicht von irgendwo kopieren kann). Aber es geht auch ohne viel Aufwand und wesentlich schneller – mit .NET Bordmitteln.

Ausgangspunkt ist der System.Globalization Namespace.

public IList<string> GetCountryList() {
    var cultureList = new List<string>();
    var cultures = CultureInfo.GetCultures(
                       CultureTypes.AllCultures &
                       ~CultureTypes.NeutralCultures);

    foreach (var culture in cultures) {
        if (culture.LCID == 127) continue;

        var region = new RegionInfo(culture.LCID);
        if (!cultureList.Contains(region.EnglishName)) {     
            cultureList.Add(region.EnglishName);
        }
    }
    return cultureList;
}

Natürlich kann die zurückgegebene Liste auch derart erweitert werden, das nicht nur die Ländernamen sondern auch die jeweiligen ISO Kürzeln enthalten sind.

ASP.NET MVC 2 Preview 2

Das Team um Phil Haack hat die 2. Preview der kommenden Version 2 des ASP.NET MVC Frameworks veröffentlicht. Die neue Version bringt einige Verbesserungen und Erweiterungen mit z.B.:

  • Client Side Validation
  • Model Validation Provider
  • Areas
  • Metadata Providers

Mehr Information in Phil Haack’s Blog

ASP.NET MVC 1.0 final verfügbar

Es ist vollbracht. Seit heute steht das ASP.NET MVC Framework in der finalen Version 1.0 zum Download bereit. Die besten Glückwünsche an das Entwicklerteam um Phil Haack für dieses großartige und moderne Framework.

Kostenloses ASP.NET MVC eBook Tutorial

Scott Guthrie hat gestern seinen Beitrag zum kommenden ASP.NET MVC Buch als kostenloses eBook zur Verfügung gestellt. Dieses bietet auf 185 Seiten ein komplettes end-to-end Tutorial zum Erstellen einer ASP.NET MVC Applikation. Das Tutorial bezieht sich auf die “NerdDinner” Applikation.  Der SourceCode steht auf CodePlex zum Download bereit.

Hier die Links nochmal zusammen gefasst:

Post von ScottGu

Download des eBooks als PDF

Download der Beispielapplikation von Codeplex

ASP.NET MVC 1.0 RC2 verfügbar

Seit heute steht der Release Candidat 2 des ASP.NET MVC Frameworks zum Download bereit. Die wichtigsten Änderungen gegenüber dem RC1:

  • Das Setup setzt zwingend das .NET Framework 3.5 SP1 voraus
  • Neuer Server-only Installationsmodus
  • Bin Deployment auf Hosts ohne SP1 ist weiterhin möglich

Mehr Infos in den Release Notes und in Phil Haack’s Post

ASP.NET MVC 1.0 RC verfügbar

Wie ScottGu in seinem Blog ankündigte, steht das neue Microsoft ASP.NET MVC Framework als “Release Candidate” zum Download bereit. Dieses enthält neben Bug fixes auch eine Reihe von Detailverbesserungen und neuen Features, die es nicht mehr in die Beta geschafft hatten. Die finale Version wird voraussichtlich nächsten Monat verfügbar sein.

Download
Details zum RC direkt in ScottGu’s Blog
Infos zum ASP.NET MVC Framework

Get Adobe Flash playerPlugin by wpburn.com wordpress themes