当模型是子模型的集合

时间:2016-03-25 15:05:19

标签: c# asp.net-mvc validation data-annotations

我有一个需要多个模型才能正常工作的视图。所以,我创建了一个模型,它是多个(子)模型的集合。这是模型。

public class PolicyDetail
{
    public Policy Policy { get; set; }
    public IEnumerable<Insured> Insureds { get; set; }
    public IEnumerable<Risk> Risks { get; set; }
    public IEnumerable<Construction> Constructions { get; set; }
}

以下是其中一个子模型的示例,它是数据库中的实际实体:

public class Policy
{
    [Key]
    public int PolicyID { get; set; }

    [DisplayName("Policy Number")]
    public Guid PolicyNumber { get; set; }

    [Required(ErrorMessage = "Please enter a valid Effective Date.")]
    [DataType(DataType.DateTime)]
    [DisplayName("Effective Date")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime EffDate { get; set; }

    [Required(ErrorMessage = "Please enter a valid Expiration Date.")]
    [DataType(DataType.DateTime)]
    [DisplayName("Expiration Date")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime ExpDate { get; set; }

    public Boolean IsActive { get; set; }
}

这一切都运作良好,直到我尝试提交有错误的表单来测试验证。我应该已经看到了这一点(可能?)但是因为实际模型上没有任何验证标签,所以它总是通过if(ModelState.IsValid)检查。是否有某种方法可以强制或继承子类中的所有数据注释?

或者,我是否会使用其他模型集合的模型来解决这个问题?问题是,我希望能够从同一视图编辑/添加多个数据库实体。

修改

Josh Carroll的{p> This article看起来确实是我需要的。但是当我实现它时,我得到一个Null Object错误。这就是我正在做的事情:

public class PolicyDetail
{
    [Required, ValidateObject] 
    public Policy Policy { get; set; }
    public IEnumerable<Insured> Insureds { get; set; }
    public IEnumerable<Risk> Risks { get; set; }
    public IEnumerable<Construction> Constructions { get; set; }
}

然后在覆盖方法中,他提供:

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var results = new List<ValidationResult>();
        var context = new ValidationContext(value, null, null);

        Validator.TryValidateObject(value, context, results, true);

        if (results.Count != 0)
        {
            var compositeResults = new CompositeValidationResult(String.Format("Validation for {0} failed!", validationContext.DisplayName));
            results.ForEach(compositeResults.AddResult);

            return compositeResults;
        }

        return ValidationResult.Success;
    }
}

参数&#34;值&#34;是null,所以它在这一行上出错:

Validator.TryValidateObject(value, context, results, true);

我错过了什么吗?做错了什么?

1 个答案:

答案 0 :(得分:1)

您可以使用以下方法手动调用子模型上的验证:https://msdn.microsoft.com/en-us/library/dd411772.aspx

var context = new ValidationContext(model.Policy, serviceProvider: null, items: null);
var validationResults = new List<ValidationResult>();

bool isValid = Validator.TryValidateObject(model.Policy, context, validationResults, true);

然后,您可以使用ModelState.AddModelError来构建响应。

绝对不是最优雅的解决方案,但可能比重写你所拥有的更容易。