Подтвердить что ты не робот

Настроить сообщение об ошибке MVC для недопустимого DateTime в ASP.NET MVC4

У меня возникли проблемы с указанием сообщения об ошибке для проверки входного значения DateTime с использованием аннотаций данных в моей модели. Я действительно хотел бы использовать правильный валидатор DateTime (в отличие от Regex и т.д.).

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

Я по-прежнему получаю сообщение о проверке даты по умолчанию: "Дата поля должна быть датой".

Я что-то пропустил?

4b9b3361

Ответ 1

У меня есть одно грязное решение.

Создать собственное связующее устройство:

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

Ответ 2

Добавьте следующие ключи в Application_Start() в Global.asax

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

Создайте YourResourceName.resx внутри App_GlobalResources и добавьте следующие клавиши

  • FieldMustBeDate Поле {0} должно быть датой.
  • FieldMustBeNumeric Поле {0} должно быть числом.
  • PropertyValueInvalid Значение {{0} "недействительно для {1}.
  • PropertyValueRequired Требуется значение.

Ответ 3

Я нашел одно обходное решение.

Вы можете оставить свою модель нетронутой.

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

Ответ 4

Я обошел эту проблему, изменив ошибку в коллекции 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);
        }
    }

Ответ 5

Попробуйте с выражением регулярного выражения, например

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

или проверьте это