2016-03-23 3 views
1

Ich bin derzeit ein Formular erstellen, die den Benutzer zur Eingabe ihres Geburtsdatums erfordert. Ich habe festgestellt, dass der benutzerfreundlichste Weg, dies zu tun, durch separate Eingabefelder für Datum, Monat und Jahr erfolgt.ASP.NET MVC Model bindING separater Tag, Monat, Jahr Zeichenfolge Felder zu einzelnen DateTime-Objekt

Ich habe eine stark typisierte Ansicht, die Textfelder für Geburtstag, Geburtsmonat und Geburtsjahr enthält. Sobald das Formular auf dem Server veröffentlicht ist, müssen diese übersetzten Zeichenfolgewerte in ein korrektes DateTime-Objekt konvertiert werden. Ich erzeuge gerade dieses DateTime-Objekt in meinem benutzerdefinierten Validator, der Altersvalidierungstests durchführt, aber ich glaube, dass es einen weitaus besseren Ansatz gibt.

Bisher habe ich versucht, den Bau des Datetime-Objekt in der Modellbauer wie folgt:

public class Applicant 
{ 
    [Required(ErrorMessage = "Day Required")] 
    public string DobDay { get; set; } 
    [Required(ErrorMessage = "Month Required")] 
    public string DobMonth { get; set; } 
    [Required(ErrorMessage = "Year Required")] 
    [BirthDateValidation("DobDay", "DobMonth")] 
    public string DobYear { get; set; } 

    public DateTime BirthDate { get; set; } 

    public Applicant() 
    { 
     this.BirthDate = new DateTime(Convert.ToInt32(this.DobYear), Convert.ToInt32(this.DobMonth), Convert.ToInt32(this.DobDay)); 
    } 
} 

Gibt es eine Möglichkeit, diese Aufgabe mehr automatisiert zu machen, wie ich oben versucht haben, so dass, wenn die Form auf dem Server ein DateTime-Objekt erstellt wird automatisch mit den gebuchten Geburtstag, Geburtsmonat, Geburtsjahr Formularwerte?

+0

Ihr Konstruktor wird nicht mit der Arbeit Modell zu binden. Sie können einen benutzerdefinierten ModelBinder erstellen, um die Formulardaten zu lesen und Ihre DateTime-Eigenschaft zu erstellen. –

+0

Was meinst du mit _more automated_? Und warum definieren Sie diese Eigenschaften nicht als "int" anstatt "string"? –

+0

möglicherweise eine schlechte Wahl der Wörter, aber ich suchte nach einer Möglichkeit für den Konstruktor, um das DateTime-Objekt zu generieren, aber nach dem Stephen ist dies möglich. – CodeMonkey

Antwort

1

ein benutzerdefiniertes Modell Binder verwenden:

public class MyCustomBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, 
          ModelBindingContext bindingContext) 
    { 
     HttpRequestBase request = controllerContext.HttpContext.Request; 

     string day = request.Form.Get("DobDay"); 
     string month = request.Form.Get("DobMonth"); 
     string year = request.Form.Get("DobYear"); 
     //etc.. 
     return new Applicant 
     { 
      BirthDate = new DateTime(Convert.ToInt32(year), Convert.ToInt32(month), Convert.ToInt32(day)) 
      //etc.. 
     }; 
    } 
} 

[HttpPost] 
public ActionResult Save([ModelBinder(typeof(MyCustomBinder))] Applicant applicant) 
{ 
    return View(); 
} 
+0

Sieht vielversprechend aus, obwohl es so aussieht, als würde es nur für eine DateTime funktionieren. Ich werde mehrere DateTime haben Gibt es eine Möglichkeit, dies für alle Termine zu tun, ohne den obigen Code zu duplizieren? – CodeMonkey

+0

Natürlich, wo Sie die Bewerbermodellklasse zurückgeben, können Sie beliebig viele Eigenschaften auffüllen. So können Sie so viele Daten haben, wie Sie möchten, wenn sie auf dem Modell sind. Der benutzerdefinierte Modellordner ist nur eine Ebene zwischen den Formularwerten und dem Controller, sodass Sie Ihre Logik dort ausführen können. –

+0

[Dieser alte Beitrag] (http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx) von Scott Hanselman hat sehr geholfen – gldraphael

Verwandte Themen