Как использовать аннотации данных в ViewModel? - PullRequest
4 голосов
/ 26 мая 2011

Я использую службы RIA с LinqToEntitiesDomainService <> и Silverlight 5 Beta для генерации кода DomainContext на стороне клиента. У меня есть Аннотации данных в моих Моделях / Сущностях для выполнения основных проверок, и при непосредственном использовании Моделей элементы управления, такие как DataForm, выполняют проверки прямо из коробки. Но я оборачиваю свою модель во ViewModel, поэтому я теряю всю эту автоматическую проверку. Вот упрощенный пример:

// In DataModel assembly, regenerated on the client side by RIA Services 
public class PetModel 
{
    [Required]
    public string Name { get; set; }
}

// Only on the client side
public class PetViewmodel
{
    private PetModel _model;

    public PetViewmodel(PetModel model)
    {
        _model = model;
    }

    public string Name
    {
        get { return _model.Name; }
        set { _model.Name = value; }
    }
}

Мой вопрос: как я могу гарантировать, что Name считается Required на стороне клиента, не дублируя все мои аннотации в ViewModel? (Возможно, в будущем мне придется использовать эти объекты с различными моделями представления - и я бы хотел оставить те же аннотации)

Я думал о ручном добавлении атрибута MetadataType в ViewModel, указывая на тип модели:

[MetadataType(typeof(PetModel))]  
public class PetViewmodel
{
...
}

Но, увы, MetadataTypeAttribute недоступен в версии Silverlight 5 System.ComponentModel.DataAnnotations.

Редактировать: Уточнение - метаданные для моих сущностей включены в сущности с вложенным классом. Я кодирую этот класс вручную, потому что моя модель L2E находится в отдельной сборке, поэтому мастер DomainService не сгенерирует ее для меня.

[MetadataType(typeof(Metadata))]  
public partial class PetModel 
{
    [Required]
    public string Name { get; set; }

    public class Metadata 
    {
        [Required]
        public string Name { get; set; }
    }
}

Это должно быть именно так, как мастер будет генерировать метаданные, если я правильно понимаю. Генератор кода RIA Services генерирует правильные аннотации данных в коде клиента, поэтому он правильно их подбирает.

1 Ответ

1 голос
/ 13 июня 2011

Я нашел способ сделать это. В надежде, что это поможет кому-то в будущем:

Я использовал базовый класс для модели представления, которая выполняет проверки. В этом базовом классе я реализую INotifyDataErrorInfo и переопределяю метод NotifyOfPropertyChange (это часть Caliburn.Micro , но если вы не используете его, вы можете просто присоединиться к PropertyChanged событие для модели). В обработчике событий я выполняю проверку этого свойства. В коде проверки я использую отражение, чтобы найти свойство с тем же именем и любые атрибуты проверки для свойства (RequiredAttribute, RangeAttribute и т. Д.). Затем я использую значения из этих свойств, чтобы проверить новое значение измененного свойства, создав объекты ValidationResult и добавив их к List<ValidationResult>. Если все «локальные» проверки пройдены, то я приступаю к выполнению «удаленных» проверок (т. Е. Проверок, которые требуют взаимодействия с сервером, например проверки на уникальность).

Это было много работы, но, к сожалению, это - или что-то подобное - необходимо. Кажется, что все примеры MS не используют MVVM. Я думал, что это просто для того, чтобы они были короткими / простыми, но команда Silverlight в MS, похоже, не уделяла серьезного внимания MVVM при разработке объектной модели.

...