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

asp.net-mvc-3 – 企业中业务实体验证的首选方法

让我先说明这个问题并说明使用实体框架不是我们的选择.

在我们的金融机构中,我们拥有将在整个解决方案中使用的业务实体.有些人拥有其他人没有的UI.验证和业务规则必须包含在实体中.

我针对为我生成的DAL和DTO进行编码,这些DAL使用procs在DB上运行CRUD(可能是sql可能是Oracle).

因此,当我创建MVC,WCF,控制台应用程序等时,如果可以实现更好的验证方法,那么问题一直在唠叨.

以下是实体对象中的几个典型属性

[DefaultValue("")]
public string Branch {
    get { return _branch; }
    set {
        if (value != null && value == _branch) return;
        const string propertyName = "Branch";
        ValidationInstance.Clear(propertyName);
        ValidationInstance.Validaterequired(propertyName,value);
        ValidationInstance.ValidateNumeric(propertyName,value);
        ValidationInstance.ValidateLength(propertyName,value,2);
        _branch = value;
        if (EntityState != EntityStateType.New)
            EntityState = EntityStateType.Changed;
    }
}

    [DefaultValue(0)]
public decimal HighDefermentMargin {
    get { return _highDefermentMargin; }
    set {
        if (value == _highDefermentMargin) return;
        const string propertyName = "HighDefermentMargin";
        ValidationInstance.Clear(propertyName);
        ValidationInstance.Validaterange(propertyName,value);
        _highDefermentMargin = value;
        if (EntityState != EntityStateType.New)
            EntityState = EntityStateType.Changed;
    }
}

正如您所看到的,有一些数据注释和对验证类的显式调用,以执行越来越详细的验证.

在MVC应用程序中,我们在viewmodel上精心复制验证,因此我们获得客户端和服务器端验证.以下是上面相同属性viewmodel版本:

[required]
[Range(0.0,99.99)]
[display(Name = "High Deferment Margin")]
public decimal HighDefermentMargin { get; set; }

这里的主要区别是实体中的验证将错误加载到Validation类的错误集合中,可以在实体保存自身时查询.如果(!IsValid)则抛出包含错误数组的自定义异常.控制器通过它们循环并将它们添加到ModelState.

我开始研究一些几乎有几百个字段的类.即使他们被OO分解,领域的数量仍然很高.这些是贷款证明等,其中包含大量单个记录的数据.必须写出许多属性的验证让我想要呕吐.我不能只编写一个实用程序来生成实体和验证,因为业务规则是驱动验证的因素,而不是数据库.意味着字段可以在db中为空,但不允许根据业务规则保持为null,或者该字段可以为null,但仅当单独的字段具有值等时.

那么,只能使用View Model中的数据注释和实体以相同的方式实现相同的结果吗?我可以为非标准验证编写自定义验证器,然后为更复杂的东西编写业务规则.验证错误是否会从实体中升级到更高级别,因此UI可以以与ModelState相同的友好方式通知用户在这种情况下,其他人在做什么?

解决方法

通常,属性上的验证属性可以获得不同的验证结果(验证通过与否),具体取决于它是在UI层,BUsiness层还是DAL中进行评估.例如,考虑一个必需属性,如果在viewmodel上应用它可能会失败,但是在业务层中它可以简单地传递,因为用户未提供的值是从其他来源提供的.
但是,验证规则(如电子邮件的格式)始终会得到相同的结果.但是,存在可能需要在业务层中重复验证的精简问题……仅仅因为Web服务器更容易受到攻击并且更容易受到攻击.但是,重复两次相同的验证并不意味着编写两次代码.您可以在公共dll中收集要应用于多个图层的所有属性,您可以在其中定义应用于同一概念实体的各种版本(viewmodel,BL,DAL)的 MetaDataType.这样,您就可以在不重复代码的情况下满足安全要求.

根据Saravanan的建议,您可以使用异常将在其他层中发现的验证错误传达给UI层(您还可以配置WCF以将异常详细信息传达给客户端)

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

相关推荐