我有以下两个实体:
public class Product
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
和视图模型
public class ProductCreateOrEditViewModel
{
public Product Product { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
Product的create视图使用此ViewModel。类别ID在视图中设置如下:
<div class="editor-field">
@Html.DropDownListFor(model => model.Product.Category.ID,new SelectList
(Model.Categories,"ID","Name"))
@Html.ValidationMessageFor(model => model.Product.Category.ID)
</div>
当表单发布时,我获得了一个带有产品和所选类别对象集的视图模型的实例,但由于Category的“Name”属性具有[Required]属性,因此ModelState无效。
就创建产品而言,我不需要或不关心“名称”属性。如何使模型绑定工作,以便不将其报告为ModelState错误?
答案 0 :(得分:4)
您应该为View创建一个正确的ViewModel。
最好的方法imo不会将您的域实体暴露给视图。
您应该从实体到视图模型进行简单的DTO展平。
这样的课程
public class ProductViewModel
{
public int ID { get; set; }
[Required]
public string Name { get; set; }
public int CategoryId? { get; set; }
public SelectList Categories { get; set; }
}
从控制器中将产品映射到viewmodel
public ViewResult MyAction(int id)
{
Product model = repository.Get(id);
//check if not null etc. etc.
var viewModel = new ProductViewModel();
viewModel.Name = model.Name;
viewModel.CategoryId = model.Category.Id;
viewModel.Categories = new SelectList(categoriesRepo.GetAll(), "Id", "Name", viewModel.CategoryId)
return View(viewModel);
}
然后,在回复帖子的操作中,您将viewModel映射回产品
[HttpPost]
public ViewResult MyAction(ProductViewModel viewModel)
{
//do the inverse mapping and save the product
}
我希望你明白这个想法