Проверка ASP.NET MVC 2 с использованием DTO вместо доменных сущностей
Я изо всех сил пытаюсь объединить две лучшие практики вместе:
- Использование DataAnnotations + ModelBinding для проверки в ASP.NET MVC 2
- Использование DTO вместо доменных сущностей при передаче данных через ViewModel
Если я хочу передать DTO вместо доменных сущностей, то для использования DataAnnotations + ModelBinding для проверки потребуется указать атрибуты проверки в моих классах DTO. Это приводит к большой дублированной работе, поскольку несколько DTO могут содержать перекрывающиеся поля с одинаковыми ограничениями проверки. Это означает, что каждый раз, когда я изменяю правило проверки в моем домене, мне нужно найти все DTO, которые соответствуют этому значению, и обновить их атрибуты проверки.
3 ответа
У вас не должно быть более одного DTO на одну сущность, поэтому вам нужно будет применять атрибуты проверки только один раз для DTO. Если вам требуется несколько объектов для представления, включите несколько DTO в качестве свойств вашей модели представления.
Вы можете найти это полезным.
И имейте в виду, что проверка живет везде. В этом нет ничего плохого, если DTO применяют валидацию пользовательского интерфейса (например, заполнение необходимых полей, дату и время в правильном формате и т. Д.) И объекты домена - валидацию домена (например, на счету есть деньги до снятия средств).
Вы не можете создать универсальную проверку. Лучшее, что вы можете сделать, - положить его в соответствующие места.
И убери это чувство о дублировании. Использование DTO обычно означает применение принципа единой ответственности. Дублирования не будет, если у вас есть 2 объекта клиента, один из которых отвечает за перенос бизнес-логики, а второй - за ее отображение.
Возможно, вы могли бы использовать метааннотации, которые помещают атрибуты в отдельный класс:
namespace MvcApplication1.Models
{
[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{
}
public class MovieMetaData
{
[Required]
public object Title { get; set; }
[Required]
[StringLength(5)]
public object Director { get; set; }
[DisplayName("Date Released")]
[Required]
public object DateReleased { get; set; }
}
}
Пример кода был заимствован из этой статьи.