Entity Framework Сложный тип Пользовательская проверка, остановка рекурсии проверки - PullRequest
5 голосов
/ 12 апреля 2011

Мы используем сложные типы для управления нашими переводимыми полями, например:

[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); 
        }
    }
}

Мы требуем, чтобы поля присутствовали. Но в некоторых случаях поле Translated необязательно, например:

public class Question
{
    ...

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

    ...
}

Однако кажется, что атрибут Optional вычисляется, и когда он возвращает false, с результатом ничего не делается.

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

Когда я добавляю необязательный атрибут к не сложному типу, он работает как положено, сообщение об ошибке всегда будет Foo.

Конечная цель - позволить описанию быть пустым в обоих случаях, но когда заполнено одно из полей, ошибки, конечно, должны распространяться.

Остановка рекурсии проверки приведет к тому, что поле будет необязательным, но это также предотвратит проверку полей в случае, если они заполнены .

Есть идеи, как этого добиться?

Ответы [ 2 ]

7 голосов
/ 24 апреля 2011

Использование аннотации данных [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 голосов
/ 26 апреля 2011

Это то, что я делаю сейчас.Недостатком является то, что для каждого типа Translated (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 {}
...