ASP.NET MVC 3 - установка пустого поля в DTO при привязке к HTTP POST вместо сбоя - PullRequest
0 голосов
/ 03 января 2012

У меня есть действие контроллера HttpPost, которое принимает объект DTO в простой форме.

[HttpPost]
public ViewResult Index(ResultQueryForm queryForm)
{
   ...
}

public class ResultQueryForm
{
   public DateTime? TimestampStart { get; set; }
   public DateTime? TimestampEnd { get; set; }
   public string Name { get; set; }
}

Объект DTO имеет пустые поля даты и времени, используемые для создания диапазона. Причина, по которой он установлен в nullable, заключается в том, что форма, связанная с моделью, является формой запроса, и пользователю не нужно вводить значение даты в форме.

Проблема, с которой я сталкиваюсь, заключается в том, что если пользователь вводит недопустимую дату, я хотел бы, чтобы привязка модели MVC по умолчанию предоставляла сообщение об ошибке. Это происходит безупречно, если у меня есть действие контроллера, которое принимает DateTime? введите в качестве аргумента, но так как я передаю DTO, который содержит DateTime? введите модель привязки, кажется, просто установить DateTime? переменная к нулю. Это приводит к неожиданным результатам.

Примечание:

[HttpPost]
public ViewResult Index(DateTime? startDate)
{
   // If the user enters an invalid date, the controller action won't even be run because   the MVC model binding will fail and return an error message to the user
}

Можно ли в любом случае указать привязке модели MVC "сбой", если она не может связать DateTime? значение для объекта формы DTO, вместо того, чтобы просто установить его на ноль? Есть ли способ лучше? Передача каждого отдельного ввода формы в контроллер невозможна из-за большого количества свойств в объекте формы / dto (многие из них я исключил для удобства чтения).

Ответы [ 2 ]

1 голос
/ 03 января 2012

Я думаю, вы можете создать собственный атрибут ValidationAttribute для этого.

[DateTimeFormat(ErrorMessage = "Invalid date format.")]
public DateTime? TimestampStart { get; set; }
[DateTimeFormat(ErrorMessage = "Invalid date format.")]
public DateTime? TimestampEnd { get; set; }


[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class DateTimeFormatAttribute : ValidationAttribute
{
    public override bool IsValid(object value) {

        // allow null values
        if (value == null) { return true; }

        // when value is not null, try to convert to a DateTime
        DateTime asDateTime;
        if (DateTime.TryParse(value.ToString(), out asDateTime)) {
            return true; // parsed to datetime successfully
        }
        return false; // value could not be parsed
    }
}
1 голос
/ 03 января 2012

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

if(!Model.IsValid)
{
  return View(); // ooops didn't work
}
else
{
  return RedirectToAction("Index"); //horray
}

Конечно, вы можете поместить туда все, что хотите, и вернуть объект Json, если хотите отобразить его на своей странице.

Также вам нужно добавить ValidateInput(true) вверху вашего метода действия, например: [HttpPost, ValidateInput(true)]

...