5

我们正在使用复杂类型来管理这样我们的翻译领域:实体框架复杂类型自定义验证,验证停止递归

[ComplexType] 
public class Translated 
{ 
    [Required] 
    public string NL { get; set; } 

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

    [ScaffoldColumn(false)] 
    public string TranslatedText 
    { 
     get 
     { 
      return Util.Translate(NL, EN); 
     } 
    } 
} 

我们需要的字段存在。但在某些情况下,整个翻译的领域是可选的,因为在:

public class Question 
{ 
    ... 

    [Optional(ErrorMessage="Foo")] 
    public Translated Description { get; set; } 

    ... 
} 

但是,它似乎是可选属性被计算,当它返回false没有什么,结果完成。

class OptionalAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     return false; 
    } 
} 

当我把可选属性在非复合型它能正常工作,错误信息将永远是富。

最终目标是在两种情况下都允许描述为空,但是当其中一个字段被填充时,错误当然应该传播。

停止验证递归会导致该领域是可选的,但它也能防止万一的领域,却填写的验证。

如何做到这一点任何想法?

+0

Btw。 EF CTP5是旧版本。目前verwion被称为EF 4.1 RTW(最终版本)。 – 2011-04-12 18:21:36

+0

我会用新版本测试这种情况并回报。 – 2011-04-13 18:09:35

+0

我在原始问题中勾画的情况依然成立。我想我可以覆盖我们的实体的Validate方法来检查它是否是可选的,如果是这种情况,只有在它不是空的情况下传播它的验证结果。 关于如何最好地实现这一点的任何建议?我也担心用自己的代码覆盖MVC/Framework提供的代码。 – 2011-04-16 19:19:38

回答

7

对字符串属性使用数据注释[Required]将在数据库中创建不可为空的字段。从你的描述看来,有时你会希望这两个值都为空。

我会建议实施您自己的验证定义是什么使这些字段可选。

[ComplexType] 
public class Translated : IValidatableObject 
{ 
    public string NL { get; set; } 

    public string EN { get; set; } 

    [NotMapped] 
    public string TranslatedText 
    { 
     get 
     { 
      return Util.Translate(NL, EN); 
     } 
    } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (!string.IsNullOrEmpty(NL) && string.IsNullOrEmpty(EN)) 
      yield return new ValidationResult("EN is required if NL is entered."); 

     if (!string.IsNullOrEmpty(EN) && string.IsNullOrEmpty(NL)) 
      yield return new ValidationResult("NL is required if EN is entered."); 
    } 
} 
+0

这里的要点是,该字段是否需要取决于使用此复杂类型的上下文。我当然可以创建多种复杂类型,例如'Translated','TranslatedOptional'。但这对我来说似乎很尴尬,我不知道它是否会起作用。 – 2011-04-26 07:18:55

+0

@Alessandro:前面,我对ADO.NET一无所知......但是这个定制的Validate方法看起来对我来说“非常热情”。唯一的问题是,翻译必须是(可选或强制),是吗?那听起来很像是我翻译的一个属性... public bool强制性{get;组; } ...或者我只是在愚蠢吗?如果是这样,为什么? – corlettk 2011-04-26 09:12:45

+0

它是否是可选的确实是Translated的属性,但它是由使用Translated字段的上下文静态确定的。所以它是一种财产,但不是属性。 – 2011-04-26 12:11:08

0

这就是我现在要做的。它的缺点是,对于每种翻译(Translated,TranslatedOptional,TranslatedMultiline和TranslatedMultilineOptional),你都有单独的类。

另一个缺点是我不知道如何将验证结果添加到NL en EN字段本身而不是翻译。

[ComplexType] 
public class TranslatedMultiline : IValidatableObject 
{ 
    [DataType(DataType.MultilineText)] 
    [Display(Name = "dutch", ResourceType = typeof(Caracal.Resources.GUI))] 
    public string NL { get; set; } 

    [DataType(DataType.MultilineText)] 
    [Display(Name = "english", ResourceType = typeof(Caracal.Resources.GUI))] 
    public string EN { get; set; } 

    [ScaffoldColumn(false)] 
    public string TranslatedText 
    { 
     get 
     { 
      return Util.Translate(NL, EN); 
     } 
    } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (this is IOptional) 
     { 
      if (!string.IsNullOrEmpty(NL) && string.IsNullOrEmpty(EN)) 
       yield return new ValidationResult("EN is required if NL is entered."); 
       // TODO: Translate 

      if (!string.IsNullOrEmpty(EN) && string.IsNullOrEmpty(NL)) 
       yield return new ValidationResult("NL is required if EN is entered."); 
       // TODO: Translate 
     } 
     else 
     { 
      if (string.IsNullOrEmpty(NL)) 
       yield return new ValidationResult("NL is required"); 

      if (string.IsNullOrEmpty(EN)) 
       yield return new ValidationResult("EN is required"); 

     } 
    } 
} 

[ComplexType] 
public class TranslatedMultilineOptional : TranslatedMultiline, IOptional { } 

public interface IOptional {}