在我们的应用程序中,我们有一个Domain层,其中包含带有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))
我们的问题出在控制器的POST方法上,当我们检查ModelState.IsValid时,模型无效,因为Supplier.Company为null。然后我们可以使用SelectedCompany来获取公司,但我们的问题是,这意味着我们不能做这样的事情:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SupplierEditModel model)
{
if (ModelState.IsValid)
{
model.CreateSupplier(_supplierService);
return RedirectToAction("Index");
}
return RedirectToAction("Create");
}
我们希望在创建供应商之前使用验证。
答案 0 :(得分:4)
我看到你(至少)有两个选择:
如果视图中不需要,您可以展平视图模型并省略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
}
(注意:您的数据注释应该在视图模型上,而不是域模型。)
或
您可以在检查ModelState
属性
IsValid
错误
ModelState.Remove(string key, ModelState);
这里的最佳做法可能是使用扁平模型,原因有两个。首先,通常只是发送视图所需的内容而不是更好的做法。如果视图没有对Supplier.Company执行任何操作,则它不应该是模型的一部分。二,使用ModelState.Remove方法虽然有效,但有些人可能会认为它是一个小小的kludgy。您可能会在代码审查中稍微破坏您的印章;)
答案 1 :(得分:2)
您可以在检查Company
之前从ModelState
移除IsValid
:ModelState.Remove("Supplier.Company")
答案 2 :(得分:-1)
public class OrderViewModel
{
[Display(Name = "Customer")]
[Required(ErrorMessage = "Please select customer.", AllowEmptyStrings = false)]
public string CustomerName { get; set; }
public IEnumerable<CustomerViewModel> Customers { get; set; }
}
public class CustomerViewModel
{
public string CustomerID { get; set; }
public string CompanyName { get; set; }
}
<div class="form-group">
@Html.LabelFor(m => m.CustomerName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.CustomerName, new SelectList(Model.Customers, "CustomerId", "CompanyName"), "- Please Select -", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CustomerName, null, new { @class = "text-danger" })
</div>
</div>