根据另一个模型属性验证属性值

时间:2016-04-19 18:29:00

标签: c# asp.net-mvc

我有一个关于财产验证的问题,但是,我还没有找到合适的答案。

我有以下课程

public class IndexViewModel
{
    public Film Film { get; set; }

    public ReviewModel Review { get; set; }
}

public class ReviewModel
{
    [RequiredIf // only fire if 'Genre' is equal to Genre.Horror]
    public string Text { get; set; }
}

public class Film
{
    public string Title { get; set; }
    public Director Director { get; set; }
    public Genre Genre { get; set; }
}

public class Director
{
    public string Name { get; set; }
}

public enum Genre
{
    Horror,
    Thriller,
    SciFi,
    Drama
}

是否可以在[RequiredIf]的{​​{1}}属性中添加Text属性,该属性会根据ReviewModel模型中Genre的值触发验证。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

当需要验证的属性不在与其关联的类中时,我不建议使用验证属性。我没有看到RequiredIfAttribute实现跨越这样的模型。 (Here's a good one from a different question.

IValidatableObject的简单实现怎么样?很明显,MVC将在构建模型时检查它。

public class IndexViewModel : IValidatableObject
{
    public Film Film { get; set; }

    public ReviewModel Review { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Film.Genre == Genre.Horror && string.IsNullOrWhiteSpace(Review.Text))
        {
            yield return new ValidationResult(
                "Please provide a review for this film.",
                new string[] { nameof(Review.Text) });
        }
    }
}

答案 1 :(得分:0)

将它放在您的业务层中。

[RequiredIf // only fire if 'Genre' is equal to Genre.Horror

如果你需要把它放在你的模型上,你也可以实现

System.ComponentModel.IValidatableObject

然后使用ObjectValidator验证它。

但是根据经验,我在我的模型上做了基本的属性修饰,比如Required和StringLength,这样asp.net MVC可以接受,并将重要的业务规则转储到我的服务层,因为验证逻辑很少这很简单,通常需要外部数据元素,如对数据库的额外调用。

这实际上取决于您的使用案例。我喜欢让我的数据类变得愚蠢,因为我希望数据会被移动,因此验证逻辑会在序列化过程中丢失,即JSON序列化。