2010-06-03 22 views
0

我有一個簡單的表單,我想驗證表單提交。請注意我已經剝離出來的HTML,以便於查看MVC驗證錯誤與強類型視圖

<%=Html.TextBox("LastName", "")%> //Lastname entry 
<%=Html.ValidationMessage("LastName")%> 

<%=Html.TextBox("FirstName", "")%>//Firstname entry 
<%=Html.ValidationMessage("FirstName")%> 

<%=Html.DropDownList("JobRole", Model.JobRoleList)%> //Dropdownlist of job roles 

<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select 
    { %> 
     <li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li> 
    <% } %> 

在提交此申請表的,我想檢查兩個FirstNameLastName被填充(即非0的長度)。

在我的控制,我有:

public ActionResult Submit(string FirstName, string LastName) 
{ 
    if (FirstName.Trim().Length == 0) 
    ModelState.AddModelError("FirstName", "You must enter a first name"); 

    if (LastName.Trim().Length == 0) 
    ModelState.AddModelError("LastName", "You must enter a first name"); 

    if (ModelState.IsValid) 
    { 
     //Update database + redirect to action 
    } 

    return View(); //If ModelState not valid, return to View and show error messages 
} 

不幸的是,這種代碼邏輯產生,說明沒有對象被發現JobRoleCourses錯誤。

如果我刪除下拉列表和複選框,那麼一切正常。

的問題似乎是,當我返回View視圖期待的對象爲dropwdownlist和複選框(這是明智的,因爲這是什麼,在我看來代碼)

我怎樣才能解決這個問題?

事情我已經考慮:

  1. 在我的控制,我可以創造一個JobRoleList對象和Course對象傳遞給視圖,以便它有渲染的對象。與此相關的問題是它將覆蓋用戶已經做出的任何下拉列表/複選框選擇。
  2. 在我的控制器方法Submit的參數中,我可以同時捕獲JobRoleList對象和Course對象以傳遞迴視圖。再次,不確定這將捕獲用戶已經選擇的任何項目。

我已經做了很多谷歌搜索和閱讀,但我找不到一個好的答案。當我在書籍或在線(例如Nerddinner)中查看示例時,所有驗證示例都涉及帶有TextBox輸入的簡單表單,並且似乎並未顯示具有多個複選框和下拉列表的實例。

我在這裏遺漏了一些明顯的東西嗎?在這種情況下最好的做法是什麼?

感謝

回答

1

最好的做法將是接受視圖特定的模型。您可以擁有一個共享模型,該模型既具有呈現頁面所需的屬性,也具有用於呈現和接受發佈參數的發佈或獨立模型所需的屬性。我通常使用共享模式,因爲這意味着我可以簡單地返回我收到的模型,適當地重新填充生成菜單所需的任何數據(例如JobList和Courses)。通常我會有一個採用這種類型模型的方法,並返回一個視圖,其中填充了菜單屬性。

public ActionResult JobsView(JobsViewModel model) 
    { 
     model.JobList = db.Jobs.Select(j => new SelectListItem 
              { 
                Text = j.Name, 
                Value = j.ID.ToString() 
              }); 
     ... 
     return View(model); 
    } 

然後從任何我的行動需要這種類型的模型的視圖,這種方法以保證模型具有適當的菜單數據。

// on error, return the view 
    return JobsView(model); 

當使用一個模型,您還可以使用DataAnnotations來裝飾你的模特屬性,讓模型綁定基於該模型爲你做驗證,以及啓用客戶端驗證。現有屬性不支持的任何驗證都可以通過創建自己的屬性或在控制器操作中完成。

public class JobsViewModel 
    { 
     [Required] 
     public string FirstName { get; set; } 

     [Required] 
     public string LastName { get; set; } 

     public int JobRole { get; set; } 

     [ScaffoldColumn(false)] 
     public IEnumerable<SelectListItem> JobRoleList { get; set; } 

     ... 
    } 

    public ActionResult Submit(JobsViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      ... convert model to entity and save to DB... 
     } 

     return JobsView(model); 
    } 

然後在你的HTML

... 
<script type="text/javascript" src="<%= Url.Content("~/scripts/MicrosoftMvcValidation.js") %>"></script> 

<% Html.EnableClientValidation(); %> 

... begin form... 

<%=Html.TextBoxFor(m=> m.LastName)%> 
<%=Html.ValidationMessageFor(m => m.LastName)%> 

<%=Html.TextBoxFor(m=> m.FirstName)%> 
<%=Html.ValidationMessageFor(m => m.FirstName)%> 

<%=Html.DropDownListFor(m=> m.JobRole, Model.JobRoleList)%> 

<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select 
    { %> 
     <li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li> 
    <% } %> 
+0

感謝啓用驗證。我已經採用了你的方法,現在事情都很好。它確實覺得我的ViewModel有點臃腫,我可能會或可能不會使用數據,但對於我所做的事情,我不認爲它會給我帶來任何問題。感謝您花時間爲我提供建議。 – 2010-06-03 20:20:58

+0

@ Remnant-正如我所說的,你可以有獨立的模型(在適當的情況下使用子類化)來顯示/發佈,但是當你發生錯誤時,你需要一種方法在它們之間進行轉換,而不是僅填充缺失的位。 – tvanfosson 2010-06-03 21:05:40

0

在簡單的MVC確認您應該通過換句話說,你的意見模型中的強類型的對象。

實施例:

public ActionResult Update(Employees employee) 
{ 

if (employee.Name.Trim().Length == 0) 
     ModelState.AddModelError("Name", "Name is required."); 

// ETC.... 

}