我怎么能忽略来自MetadataType属性缺失的领域? [英] How can I ignore missing fields from the MetadataType attribute?

查看:229
本文介绍了我怎么能忽略来自MetadataType属性缺失的领域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有被映射到的ViewModels的DTO。为了避免管理验证属性(及其他属性),我想写一个单一类的所有属性的属性验证和重用它在我的ViewModels。然而,当我尝试使用元数据在不具备DTO的所有属性(所有的人都真的... ...)一个视图模型,它给了我一个 System.InvalidOperationException 例外。

例外:

乐德式métadonnéesassocié倒乐型MyProject.EntityViewModel'contient莱propriétés欧inconnus suivants冠军:AnotherProperty。 Vérifiez阙莱NOMS去CES membres记者辅助NOMS DESpropriétés杜类型的主体。

谷歌翻译:

类型'MyProject.EntityViewModel'相关的元数据的类型包含以下未知属性或字段:AnotherProperty。验证这些成员的名称相匹配的主要类型的属性的名称。

简单的例子:

 公共类实体{
    公共字符串A {搞定;组; }
    公共字符串B {搞定;组; }
    公共字符串C {搞定;组; }
}公共类EntityDT​​O {
    公共字符串A {搞定;组; }
    公共字符串B {搞定;组; }
    公共字符串C {搞定;组; }
}//这个类是用来添加属性验证,输入相关的视图模型
公共类EntityInputValidation {
    [需要]
    公共字符串A {搞定;组; }    [需要]
    公共字符串B {搞定;组; }    //注意,我们没有对C验证
}//这个类是一个ViewModel用于创建一个新的实体
[MetadataType(typeof运算(EntityInputValidation))]
公共类EntityCreateViewModel {
    //必需的,因为我们使用的InputValidation元
    公共字符串A {搞定;组; }    //注意我们没有b属性在这里,即使我们使用具有这个属性必需属性的输入验证。这是异常的来源。    // C只需要在这个视图/视图模型
    [需要]
    公共字符串C {搞定;组; }
}

由于EntityViewModel没有 AnotherProperty ,它会抛出异常。有没有一种方法,以prevent呢?


解决方案

我肯定会重新考虑直接在你的实体拥有这些注释。正如你已经可以看到,这将导致你的问题时,你需要使用实体中并不需要遵守这些验证规则的视图。这将有可能在长期内变得更糟,如果更多的意见加入其中使用您的实体。

pretty多少你拿出任何解决方案,以停止抛出异常将是一个黑客。

每个意见更新时间:


  

我不希望搜索到20视图模型,每当我们要改变验证规则......我们目前有2个网站和即将3是使用相同的DAL和业务逻辑解决方案的一部分。那是很多视图模型的保持更新。


这无疑是一个有效的关注,这也是要提出一个有效的问题。问题更是没有明确的解决方案,至少,我已经找到。

纵观在继承想法,它起初似乎是合理的。然而,这只会当你的属性适合整齐的群体,从更新的问题似乎也不会是这样的工作。

让我们以一个简单的例子:

 公共类LoginValidation
{
    [需要]
    公共字符串用户名{获得;组; }
    [需要]
    公共字符串密码{搞定;组; }
}

您可以再获得从该视图模型:

 公共类ViewModelA:LoginValidation
{
    公共字符串SomeOtherProperty {搞定;组; }
}

不过,这种带有一个问题。如果你要继承另一组验证属性怎么样?你不能,因为我们仅限于从一个类继承。我们也不能继承接口数据注释:


  

该产品团队不希望实现此功能,主要有两个原因:


  
  

      
  1. 一致性与DataAnnotations.Validator

  2.   
  3. 一致性与ASP.Net MVC的验证行为


      
      

    棘手的情景:一个类实现具有相同属性的两个接口,但对他们的冲突的属性。哪个属性会采取precedence?


  4.   

(来源:<一个href=\"http://social.msdn.microsoft.com/Forums/en-US/1748587a-f13c-4dd7-9fec-c8d57014632c/$c$c-first-dataannotations-in-interfaces?forum=adonetefx\" rel=\"nofollow\">http://social.msdn.microsoft.com/Forums/en-US/1748587a-f13c-4dd7-9fec-c8d57014632c/$c$c-first-dataannotations-in-interfaces?forum=adonetefx)

所以,如果你需要 LoginValidation 并针对特定针对某日期验证?你必须在一个中间类来创建来自继承链,只是为了能够从继承您的视图模型:

 公共类LoginAndDateValidation:LoginValidation
{
    [需要]
    公开日期时间起始日期{搞定;组; }
    [需要]
    公共DateTime的结束日期{搞定;组; }
}公共类ViewModelA:LoginAndDateValidation
{
    公共字符串SomeOtherProperty {搞定;组; }
}

你看这是怎么回事?这将变成一个完整的一塌糊涂。所以,正如我刚才所说,这将只有当你的特性融入,并在定义明确的组用于工作,但它似乎并不认为是在您的方案的情况。

要完成了,让我只是链接到一个答案空军终于发布人几年前,我一直很喜欢: HTTP: //stackoverflow.com/a/8075115/729541

I have DTOs that are mapped to ViewModels. To avoid having to manage validation attributes (and other attributes), I wanted to write the validation attributes for all the properties on a single class and reuse it on my ViewModels. However, when I try to use the Metadata on a ViewModel that does not have all the properties of the DTO (all of them really...), it gives me an System.InvalidOperationException exception.

Exception:

Le type de métadonnées associé pour le type 'MyProject.EntityViewModel' contient les propriétés ou champs inconnus suivants : AnotherProperty. Vérifiez que les noms de ces membres correspondent aux noms des propriétés du type principal.

Google translated:

The type associated metadata for type 'MyProject.EntityViewModel' contains the following unknown properties or fields: AnotherProperty. Verify that the names of these members match the names of the properties of the main type.

Simplified example:

public class Entity {
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

public class EntityDTO {
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

//This class is used to add validation attributes for input-related view models
public class EntityInputValidation {
    [Required]
    public string A { get; set; }

    [Required]
    public string B { get; set; }

    //Notice that we dont have a validation for C
}

//This class is a ViewModel used to create a new Entity
[MetadataType(typeof(EntityInputValidation))]
public class EntityCreateViewModel {
    //Required because we use the InputValidation metadata
    public string A { get; set; }

    //Notice that we do not have the B property here, even if we are using the Input Validation which has a required attribute for this property. This is where the exception comes from.

    //C is only required in this View/ViewModel
    [Required]
    public string C { get; set; }
}

Because EntityViewModel does not have AnotherProperty, it will throw an exception. Is there a way to prevent this?

解决方案

I would certainly reconsider having those annotations directly on your entity. As you can already see, this is going to cause you problems whenever you need to use that entity in a view which doesn't need to adhere to those validation rules. That will likely get worse in the long run if more views are added which use your entity.

Pretty much whatever solution you come up with to stop that throwing the exception is going to be a hack.

Updated per comments

I did not want to search into 20 view models whenever we have to change a validation rule... We currently have 2 websites and soon to be 3 that are part of the solution using the same DAL and business logic. Thats a lot of view models to keep updated.

That is certainly a valid concern, and this is also a valid question to be asking. The problem is more that there is no well-defined solution, at least that I've found.

Taking a look at the inheritance idea, it seems reasonable at first. However, this is only going to work if your properties fit into neat groups, which from your updated question seems may not be the case.

Let's take a simple example:

public class LoginValidation
{
    [Required]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
}

You could then derive a view model from that:

public class ViewModelA : LoginValidation
{
    public string SomeOtherProperty { get; set; }
}

However, this comes with a problem. What if you want to inherit another set of validation properties? You can't, as we're restricted to inheriting from one class. We also cannot inherit data annotations from interfaces:

The product team does not want to implement this feature, for two main reasons:

  1. Consistency with DataAnnotations.Validator
  2. Consistency with validation behavior in ASP.Net MVC

    tricky scenario: a class implements two interfaces that have the same property, but with conflicting attributes on them. Which attribute would take precedence?

(Source: http://social.msdn.microsoft.com/Forums/en-US/1748587a-f13c-4dd7-9fec-c8d57014632c/code-first-dataannotations-in-interfaces?forum=adonetefx)

So what if you need LoginValidation and some dates validation for a specific view? You'd have to create an inheritance chain from both in an intermediary class, just to be able to inherit from that for your view model:

public class LoginAndDateValidation : LoginValidation
{
    [Required]
    public DateTime StartDate { get; set; }
    [Required]
    public DateTime EndDate { get; set; }
}

public class ViewModelA : LoginAndDateValidation
{
    public string SomeOtherProperty { get; set; }
}

Do you see where this is going? This would turn into a complete mess. So, as I said earlier, this will only work if your properties fit into, and are used in, well-defined groups, but it doesn't seem that is the case in your scenario.

To finish up, let me just link to an answer Mystere Man posted a few years back that I've always liked: http://stackoverflow.com/a/8075115/729541

这篇关于我怎么能忽略来自MetadataType属性缺失的领域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆