在我们的应用程序中,我们有一个域层,其中包含带有用于验证的 DataAnnotations 的类。
我们在 ASP.NET MVC ui 层的模型中使用这些类。
例如:
领域层:
public class Company
{
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Description { get; set; }
// ... some model logic abreviated
}
public class Supplier
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public Company Company { get; set; }
// ... some model logic abreviated
}
在我们的 ASP.NET MVC 表示层中:
public class SupplierEditModel
{
public Supplier Supplier { get; set; }
public IEnumerable<Company> Company { get; set; }
public int SelectedCompany { get; set; }
// ... some model logic abreviated
}
在这种情况下,我们有一个包含公司 DropDownList 的页面。该列表具有约束力,如下所示:
@Html.DropDownListFor(m => m.SelectedCompany, new SelectList(Model.Companies, "Id", "Description", Model.SelectedCompany))
我们的问题出在 Controller 的 POST 方法上,当我们检查 ModelState.IsValid 时,模型无效,因为 Supplier.Company 为空。然后我们可以使用 SelectedCompany 获取公司,但我们的问题是这意味着我们不能做这样的事情:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SupplierEditModel model)
{
if (ModelState.IsValid)
{
model.CreateSupplier(_supplierService);
return RedirectToAction("Index");
}
return RedirectToAction("Create");
}
我们想在创建供应商之前使用验证。
最佳答案
我看到您(至少)有两个选择:
您可以展平您的 View 模型并省略 Supplier.Company
如果您认为不需要它。
public class SupplierEditModel
{
public int SupplierId { get; set; }
public string Name { get; set; }
public Company Company { get; set; }
public IEnumerable<Company> Company { get; set; }
public int SelectedCompany { get; set; }
// ... some model logic abreviated
}
(注意:您的数据注释应该在 View 模型上,而不是域模型上。)
或者
您可以清除
ModelState
检查之前的错误IsValid
属性(property)ModelState.Remove(string key, ModelState);
这里的最佳实践可能是使用扁平模型,原因有两个。一,通常只发送 View 需要的内容而不是其他内容是一种很好的做法。如果 View 没有对 Supplier.Company 做任何事情,那么它就不应该是模型的一部分。第二,使用 ModelState.Remove 方法虽然有效,但在某些人看来可能有点笨拙。您可能会在代码审查中遇到一些麻烦;)
关于asp.net-mvc - ModelState 验证不适用于 DropDownList 和嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15026888/