【发布时间】:2011-01-28 22:07:19
【问题描述】:
我正在使用 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; }
}
请注意,Company 具有 Subdomain,Subdomain 具有 ICollection<SubdomainActivity>。
我有 Company 和 Subdomain 的控制器。在SubdomainController 中,当我在Subdomain 的实例上调用UpdateModel()(或TryUpdateModel())时,我得到了我想要的结果。验证 Subdomain 活动的值总和为 100。
在CompanyController 中,当我在Company 的实例上调用UpdateModel() 时,它验证Subdomain.Activities 加起来也为100,这是我不想要的。无论如何,用户甚至不能从Company 编辑视图编辑Subdomain.Activites,因此告诉他们Subdomain.Activities 有错误是没有意义的。
我希望能够将一个项目添加到 validationContext.Items IDictionary 以便我可以根据上下文或类似的东西有条件地验证,但我无法弄清楚如何在不写我的情况下做到这一点自己的 IModelBinder (我想我可以这样做,但似乎有点矫枉过正)。最终我在CompanyController 中提出了这个解决方法,但我确信有一个正确的方法来处理这个问题(这包含在try catch 中)
var d = this.companyRepository.GetById(id);
bool good = TryUpdateModel(d);
if (!good)
{
if (ModelState.ContainsKey("Subdomain.Activities"))
ModelState.Remove("Subdomain.Activities");
if (!ModelState.IsValid)
throw new InvalidOperationException(string.Format("The model of type '{0}' could not be updated.", typeof(Company).FullName));
}
this.companyRepository.Save();
作为一个有趣的附注,如果我不检查模型是否有效并抛出错误,那么 companyRepository.Save() 工作正常。换句话说,EFCodeFirst 似乎没有在子域上调用 Validate,但 MVC UpdateModel 会。
谁能帮助我以更好/正确/推荐的方式来处理这个问题?
【问题讨论】:
-
如果我可以跳过对公司子域属性的验证,我认为这也可以。不过不知道该怎么做。
-
没有dontvalidateattribute什么的吗?查看 system.componentobject.dataannotations 或命名空间的名称(抱歉,我没有更多帮助,在移动设备上)。
-
我认为从 ModelState 错误中删除它很好。关于您关于 EF CTP5 未验证的问题 - 这可能是此 CTP 中的错误。它应该使用 IValidatableObject 并对其进行验证。也许这个问题可以帮助stackoverflow.com/questions/4233920/…
-
@Alxandr - 是的,我已经搜索了那个命名空间但没有成功。我尝试添加一个 CustomValidationAttribute 希望它会覆盖另一个,但它没有帮助。仍然运行子域验证。您还可以将 [ValidateInput(false)] 添加到模型中,但不能添加属性。
-
@mare - 可以期望对象图验证多远?在这种情况下,它在技术上验证子域的活动。甚至与公司无关。我更喜欢我所看到的 EFCodeFirst,而不是 TryUpdateModel 和 UpdateModel。如果我有办法在 validationContext 中设置标志,我会很高兴。必须删除模型错误是一件痛苦的事情。另外,不确定其他问题与我的关系如何。
标签: c# asp.net-mvc asp.net-mvc-3 entity-framework