2012-04-11 215 views
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; } 
} 

用於產品的創建視圖使用此視圖模型。類別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> 

當表單帖子中,我得到一個產品和所選擇的類別對象集,但因爲視圖模型的實例類的「名稱」屬性有ModelState的[必需]屬性無效。

就創建產品而言,我不需要或不關心「名稱」屬性。我如何獲得模型綁定以使其不會作爲ModelState錯誤報告?

回答

3

您應該爲您的視圖創建正確的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; } 
} 

從你的控制器A類,你的產品映射到您的視圖模型

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); 
} 

然後在到後迴應的動作,您的視圖模型映射回產品

[HttpPost] 
public ViewResult MyAction(ProductViewModel viewModel) 
{ 
    //do the inverse mapping and save the product 
} 

我希望你有想法

+0

有道理,唯一的副作用是,您將不得不在所有視圖模型類上重複模型驗證不是或者是否存在針對此的推薦方法? – 2012-04-12 01:39:32

+1

最後你會有兩個驗證層。一個「客戶端」通過視圖模型和一個「服務器端」通過您的業務邏輯層應該是 – Iridio 2012-04-12 05:10:24