2016-03-23 11 views
1

私は現在、ユーザーが生年月日を入力する必要があるフォームを作成しています。私は、これを行う最もユーザーフレンドリーな方法は、別々の日付の日、月、および年の入力フィールドを使用することであると判断しました。ASP.NET MVCモデルは、日、月、年の文字列フィールドを単一のDateTimeオブジェクトにバインドします

私は生年月日、生年月日、生年月日のテキストボックスを含む強く型付けされたビューを持っています。フォームがサーバーに送信されると、これらの送信された文字列値を適切なDateTimeオブジェクトに変換する必要があります。私は現在、Age Validationテストを実行するカスタムバリデーターでこのDateTimeオブジェクトを生成していますが、はるかに良いアプローチがあると思います。

これまでのところ、私は次のようにモデルコンストラクタでDateTimeオブジェクトを構築しようとしている:フォームがあるときになるように、私は、上記試してみましたよう

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)); 
    } 
} 

は、このタスクは、より自動化させるためにそこの方法ですDateTimeオブジェクトは、投稿された生年月日、生年月日、生年月日のフォーム値を使用して自動的に作成されます。

+0

あなたのコンストラクタ文句を言わないモデルが結合して働きます。カスタムModelBinderを作成してフォームデータを読み込んで、DateTimeプロパティを構築することができます。 –

+0

_more automated_とはどういう意味ですか?そして、なぜそれらのプロパティを 'string'ではなく' int'として定義しますか? –

+0

おそらく悪い単語の選択が、私はコンストラクタがDateTimeオブジェクトを生成する方法を探していましたが、これは可能です。 – CodeMonkey

答えて

1

カスタムモデルバインダーを使用します。

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

これは1つのDateTimeでしか動作しないようですが、有望です。私は複数のDateTimeを持っています上記のコードを複製せずにすべての日付のためにこれを行う方法はありますか? – CodeMonkey

+0

もちろん、申請者のモデルクラスを返す場所には、必要な数のプロパティを設定できます。モデル上にあれば、希望通りに多くの日付を設定することができます。カスタムモデルのバインダーは、フォームの値とコントローラーの間の単なるレイヤーなので、そこでロジックを実行できます。 –

+0

Scott Hanselmanの[この古い記事](http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx) – gldraphael

関連する問題