C# ASP.NET MVC 3-调用UpdateModel或TryUpdateModel时如何有条件地验证(IValidatableObject)?

C# ASP.NET MVC 3-调用UpdateModel或TryUpdateModel时如何有条件地验证(IValidatableObject)?,c#,asp.net-mvc,asp.net-mvc-3,entity-framework,C#,Asp.net Mvc,Asp.net Mvc 3,Entity Framework,我使用的是EFCodeFirst CTP5(尽管这不会有什么区别)和ASP.NET MVC 3。我创建了以下实体: public class Company { public int CompanyID { get; set; } public int SubdomainID { get; set; } public virtual Subdomain Subdomain { get; set; } } public class Subdomain :

我使用的是EFCodeFirst CTP5(尽管这不会有什么区别)和ASP.NET MVC 3。我创建了以下实体:

public class Company
{
    public int CompanyID { get; set; }    
    public int SubdomainID { get; set; }
    public virtual Subdomain Subdomain { get; set; }    
}

public class Subdomain : IValidatableObject
{
    public int SubdomainID { get; set; }    
    public virtual ICollection<SubdomainActivity> Activities { get; set; }    
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        int activitySum = Activities.Sum(x => x.Value);
        if (activitySum != 100)
        {
            yield return new ValidationResult(string.Format("The Activity percentages must add up to 100. Current sum is {0}", activitySum), new[] { "Activities" });
        }
    }    
}
public class SubdomainActivity
{        
    public int ActivityID { get; set; }    
    public int Value { get; set; }
}
有趣的是,如果我不检查模型是否有效并抛出错误,那么companyRepository.Save()就可以正常工作。换句话说,EFCodeFirst似乎不在子域上调用Validate,但MVC UpdateModel会调用


有人能帮我找到更好/正确/推荐的方法来处理这个问题吗

我找到了一种更优雅地处理这个问题的方法。我没有在
子域上实现
IValidatableObject
,而是在子域的Activities属性上使用
[CustomValidation]
属性。在验证我的问题中的
公司
实例时,不会调用此函数,并且我仍然会得到有关活动的专门验证。希望有一天这能帮助某人

public class Subdomain
{
    public int SubdomainID { get; set; }

    [CustomValidation(typeof(Subdomain), "ValidateActivities")]
    public virtual ICollection<SubdomainActivity> Activities { get; set; }
    public static ValidationResult ValidateActivities(ICollection<SubdomainActivity> activities)
    {
        if (activities.Count > 0)
        {
            int activitySum = activities.Sum(x => x.Value);
            if (activitySum != 100)
            {
                return new ValidationResult(string.Format("The Activity percentages must add up to 100. Current sum is {0}", activitySum), new[] { "Activities" });
            }
        }
        return ValidationResult.Success;
    }
}
公共类子域
{
public int SubdomainID{get;set;}
[CustomValidation(typeof(子域),“ValidateActivities”)]
公共虚拟ICollection活动{get;set;}
公共静态验证结果验证活动(ICollection活动)
{
如果(activities.Count>0)
{
int activitySum=activities.Sum(x=>x.Value);
如果(activitySum!=100)
{
返回新的ValidationResult(string.Format(“活动百分比之和必须达到100。当前总和为{0}”,activitySum),new[]{“活动”});
}
}
返回ValidationResult.Success;
}
}
公共IEnumerable验证(ValidationContext ValidationContext)
{
int activitySum=Activities.Sum(x=>x.Value);
如果(activitySum!=100)
{
返回新的ValidationResult(string.Format(“活动百分比之和必须达到100。当前总和为{0}”,activitySum),新[]{“活动”});
}
}  
下面修改Validate()方法怎么样

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    int activitySum = Activities.Sum(x => x.Value);
    if (Activities.Count != 0 && activitySum != 100)
    {
        yield return new ValidationResult(string.Format("The Activity percentages must add up to 100. Current sum is {0}", activitySum), new[] { "Activities" });
    }
}  
公共IEnumerable验证(ValidationContext ValidationContext) { int activitySum=Activities.Sum(x=>x.Value); 如果(Activities.Count!=0&&activitySum!=100) { 返回新的ValidationResult(string.Format(“活动百分比之和必须达到100。当前总和为{0}”,activitySum),新[]{“活动”}); } }
如果我可以跳过公司子域属性的验证,我想这也行。不知道该怎么做。难道没有dontvalidateattribute之类的东西吗?查看system.componentobject.dataannotations或名称空间的名称(抱歉,我在移动设备上没有更多帮助)。我认为将其从ModelState错误中删除是可以的。关于您关于EF CTP5未验证的问题-这可能是本CTP中的一个错误。它应该使用IValidatableObject并对其进行验证。也许这个问题可以帮助@Alxandr-是的,我搜索了这个名称空间,但没有成功。我尝试添加一个CustomValidationAttribute,希望它能覆盖另一个,但没有帮助。仍然运行子域验证。您还可以将[ValidateInput(false)]添加到模型中,但不能添加属性。@mare-您希望对象图向下验证多远?在这种情况下,它在技术上验证子域的活动。甚至和公司没有关系。我更喜欢EFCodeFirst,而不是TryUpdateModel和UpdateModel。如果我有办法在validationContext中设置一个标志,我会很高兴。必须消除模型错误是一种痛苦。另外,我不知道另一个问题与我的问题有什么关系。
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    int activitySum = Activities.Sum(x => x.Value);
    if (activitySum != 100)
    {
        yield return new ValidationResult(string.Format("The Activity percentages must add up to 100. Current sum is {0}", activitySum), new[] { "Activities" });
    }
}  
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    int activitySum = Activities.Sum(x => x.Value);
    if (Activities.Count != 0 && activitySum != 100)
    {
        yield return new ValidationResult(string.Format("The Activity percentages must add up to 100. Current sum is {0}", activitySum), new[] { "Activities" });
    }
}