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 {}