微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何在ViewModel上使用数据注释?

我正在使用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被认为是必需的而不重复viewmodel中的所有注释? (我将来可能不得不将这些实体与不同的viewmodel一起使用 – 我想保留相同的注释)

我想到手动将MetadataType属性添加viewmodel,指向Model类型:

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

但是,MetadataTypeAttribute在System.ComponentModel.DataAnnotations的Silverlight 5版本中不可用.

编辑:澄清 – 我的实体的元数据包含在具有嵌套类的实体中.我手动编写此类,因为我的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服务代码生成器在客户端代码生成正确的数据注释,因此它正确地进行选择.

解决方法

我找到了一种方法来做到这一点.希望它能在未来帮助某人:

我为执行验证的viewmodel使用了一个基类.在该基类上,我实现了INotifyDataErrorInfo,并且我重写了NotifyOfPropertyChange方法(这是Caliburn.Micro的一部分,但如果你没有使用,你可以轻松地附加到模型的PropertyChanged事件).在事件处理程序中,我对该属性执行验证.在验证代码中,我使用反射来查找相同名称属性,以及属性上的任何验证属性(requiredAttribute,RangeAttribute等).然后,我使用这些属性中的值来验证已更改属性的新值,创建ValidationResult对象并将它们添加到List< ValidationResult>.如果所有“本地”验证都通过,那么我继续执行“远程”验证(即需要与服务器交互的验证,例如检查唯一性).

这是很多工作,但不幸的是,这或者类似的东西是必要的.所有MS示例似乎都不使用MVVM.我认为这只是为了让它们简短/简单,但MS的Silverlight团队似乎没有在设计对象模型时认真考虑MVVM.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐