3

我有以下 2 个实体:

 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 的创建视图使用此 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 错误?

4

1 回答 1

4

您应该为您的视图创建一个正确的 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; }
}

从您的控制器中,您将产品映射到您的视图模型

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
}

我希望你能明白

于 2012-04-11T16:17:00.537 回答