2013-02-22 78 views
4

在我們的應用程序中,我們有一個Domain層,其中包含用於驗證的DataAnnotations的類。ModelState驗證不與DropDownList和嵌套對象配合使用

我們在我們的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爲空。然後,我們可以得到使用SelectedCompany公司,但我們的問題是,這意味着我們不能做這樣的事情:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(SupplierEditModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     model.CreateSupplier(_supplierService); 
     return RedirectToAction("Index"); 
    } 

    return RedirectToAction("Create"); 
} 

我們想創建供應商之前,使用驗證。

+2

您可以從'ModelState'檢查'之前刪除'Company' IsValid':'ModelState.Remove(「Supplier.Company」)'。 – Zabavsky 2013-02-22 15:02:18

+0

@Zabavsky你應該提交這個答案,我會upvote它並可以接受它(取決於其他答案)。 – Gilles 2013-02-22 15:05:25

+0

我發佈它作爲答案。 – Zabavsky 2013-02-22 15:06:40

回答

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 
} 

(注:數據註解應該是在視圖模型,而不是域模型。)

你可以檢查IsValid財產

ModelState.Remove(string key, ModelState); 
之前清除 ModelState錯誤

這裏的最佳實踐可能會使用扁平化模型,原因有兩個。一,通常是一個好的做法,只發送它所需要的視圖,而不是更多。如果視圖對Supplier.Company沒有做任何事情,那麼它不應該是模型的一部分。二,使用ModelState.Remove方法雖然有效,但有些人可能會認爲它有點笨拙。你可能會得到您的印章搗毀在代碼審查位;)

2

您可以從ModelState刪除Company檢查IsValid前:ModelState.Remove("Supplier.Company")

-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> 
+0

最好解釋答案,然後只給出代碼。 – 2017-09-03 17:50:31