web-dev-qa-db-ja.com

ASP.NET MVC4で無効なDateTimeのエラーメッセージMVCをカスタマイズする

モデルのデータ注釈を使用してDateTime入力値を検証するためのエラーメッセージの指定に問題があります。 (正規表現などではなく)適切なDateTimeバリデーターを実際に使用したいと思います。

[DataType(DataType.DateTime, ErrorMessage = "A valid Date or Date and Time must be entered eg. January 1, 2014 12:00AM")]
public DateTime Date { get; set; }

「フィールド日付は日付でなければなりません」というデフォルトの日付検証メッセージが引き続き表示されます。

何か不足していますか?

19
Chris Albrecht

汚い解決策があります。

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

public class CustomModelBinder<T> : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if(value != null && !String.IsNullOrEmpty(value.AttemptedValue))
        {
            T temp = default(T);
            try
            {
                temp = ( T )TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value.AttemptedValue);
            }
            catch
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, "A valid Date or Date and Time must be entered eg. January 1, 2014 12:00AM");
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
            }

            return temp;
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}

そして、Global.asax.csで:

protected void Application_Start()
{
    //...
    ModelBinders.Binders.Add(typeof(DateTime), new CustomModelBinder<DateTime>());
9
x2.

Global.asaxでApplication_Start()に次のキーを追加します

ClientDataTypeModelValidatorProvider.ResourceClassKey = "YourResourceName";
DefaultModelBinder.ResourceClassKey = "YourResourceName";

YourResourceName.resxApp_GlobalResourcesフォルダ内に作成し、次のキーを追加します

  • FieldMustBeDateフィールド{0}は日付でなければなりません。
  • FieldMustBeNumericフィールド{0}は数値でなければなりません。
  • PropertyValueInvalid値 '{0}'は{1}では無効です。
  • PropertyValueRequired値が必要です。
39
cilerler

簡単な回避策が1つ見つかりました。

モデルはそのままにしておくことができます。

[DataType(DataType.Date)]
public DateTime Date { get; set; }

次に、ビューの 'data-val-date'属性をオーバーライドします。

@Html.TextBoxFor(model => model.Date, new
{
    @class = "form-control",
    data_val_date = "Custom error message."
})

または、メッセージをパラメーター化する場合は、静的関数String.Formatを使用できます。

@Html.TextBoxFor(model => model.Date, new
{
    @class = "form-control",
    data_val_date = String.Format("The field '{0}' must be a valid date.",  
                                    Html.DisplayNameFor(model => model.Date))
})

リソースと同様:

@Html.TextBoxFor(model => model.Date, new
{
    @class = "form-control",
    data_val_date = String.Format(Resources.ErrorMessages.Date,  
                                   Html.DisplayNameFor(model => model.Date))
})
14
Pavol Korvas

アクションメソッドの開始時にModelStateコレクションのエラーを修正して、この問題を回避しました。このようなもの:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult MyAction(MyModel model)
    {
        ModelState myFieldState = ModelState["MyField"];
        DateTime value;
        if (!DateTime.TryParse(myFieldState.Value.AttemptedValue, out value))
        {
            myFieldState.Errors.Clear();
            myFieldState.Errors.Add("My custom error message");
        }

        if (ModelState.IsValid)
        {
            // Do stuff
        }
        else
        {
            return View(model);
        }
    }
1
Martin Brown

次のような正規表現アノテーションで試してください

[Required]
[RegularExpression("\d{4}-\d{2}-\d{2}(?:\s\d{1,2}:\d{2}:\d{2})?")]
public string Date { get; set; }

または これをチェック

0
Sandy