2011-09-06 31 views
3

我有以下模式:asp.net MVC 3驗證爲Id字段與EF代碼第一

public class Product 
{ 
    [Key] 
    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Required] 
    [StringLength(10)] 
    public string ProductCode { get; set; } 

    [Required] 
    [StringLength(40)] 
    public string ProductName { get; set; } 
} 

和下面的一對添加方法在控制器的:

[HttpGet] 
public ActionResult Add() 
{ 
    return View(); 
} 

[HttpPost] 
[ValidateInput(false)] 
[ValidateAntiForgeryToken] 
public ActionResult Add(Product product) 
{ 
    productRepository.Add(product); 

    return RedirectToAction("Index"); 
} 

這是添加視圖:

@using Models 
@model Product 

<h2>Add Product</h2> 

@using (@Html.BeginForm("Add", "Home")) { 
    @Html.AntiForgeryToken() 
    @Html.EditorForModel() 
    <input type="submit" id="btnSubmit" value="Submit"/> 
} 

一切都顯示得很好,很遺憾我無法提交表單。我花了一段時間才發現Id字段得到驗證。事實上,如果我刪除HiddenInput屬性,我可以看到提交它告訴我Id字段是必需的。

有沒有辦法在使用EditorForModel()時將其標記爲不需要?

回答

7

如果你必須保持主鍵模型的一部分,那麼你需要重寫默認DataAnnotationsModelValidatorProvider需要值類型。以下內容添加到Application_Start方法中的Global.asax.cs

ModelValidatorProviders.Providers.Clear(); 
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider()); 
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 
+0

是的是的!謝謝......只有一件事,你有一個錯字(我相信),它是'DataAnnotationsModelValidatorProvider' - 你有一個額外的「元數據」。 –

+0

糟糕!你是對的。我更新了我的答案,以糾正我的大腦鎖定(手指打字,否則大腦被鎖定)。 – counsellorben

1

您應該考慮使用視圖模型,而不是將域實體作爲模型發送到視圖。

public class ProductAddModel 
{ 
    [Required] 
    [StringLength(10)] 
    public string ProductCode { get; set; } 

    [Required] 
    [StringLength(40)] 
    public string ProductName { get; set; } 
} 

然後使用工具像AutoMapper到視圖模型映射回你的域模型

[HttpPost] 
[ValidateInput(false)] 
[ValidateAntiForgeryToken] 
public ActionResult Add(ProductAddModel productAddModel) 
{ 
    if (ModelState.IsValid) 
    { 
     Product product = Mapper.Map<ProductAddModel, Product>(productAddModel); 

     productRepository.Add(product); 
    } 

    return RedirectToAction("Index"); 
} 
+0

這不是一個域的實體,它只是一個DTO ...我的原則是,模型服務的意見,所以這是一個視圖模型。問題是Edit方法需要Id,所以這意味着兩個視圖模型,我不願意這樣做。 (如果沒有其他方法,我會這樣做,但我希望實際上有辦法告訴它至少在某些情況下不要檢查Id。) –

+0

@Marcel自ID屬性是值類型MVC將添加所需的驗證。你可以讓它爲空'public int? Id {get;組; }'因爲你說'Product'是一個DTO。 – Eranga

+0

我不認爲EF會讓我把主鍵設爲空,即使是這樣,我也不喜歡這個主意。所以我想我的問題的答案是「不」,然後呢? –