2010-11-08 184 views
2

我有一個非常簡單的MVC 2表單。它有兩個下拉菜單,用戶和角色。無論我選擇什麼,員工下拉菜單都會通過驗證,而角色下拉菜單則不會。雖然我打算實現一個選項,但沒有默認的「空白」選項,這就是爲什麼我需要驗證才能工作。它無法同時驗證客戶端和服務器。我只是不明白爲什麼一個人會工作,一個人不工作!ModelState.IsValid在應該爲true時返回false

的形式爲:

<% using (Html.BeginForm()) {%> 

    <%:Html.ValidationSummary(true) %> 
    <%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%> 

    <p> 
     <input type="submit" value="Add New User" /> 
    </p> 

    <% } %> 

<% Html.EndForm(); %> 

的編輯模板:

<tr> 
    <td> 
     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.UserId) %> 
      <%: Html.RequiredMarkFor(model => model.UserId) %> 
     </div> 
    </td>  
    <td>  
    <div class="editor-field"> 
     <%: Html.DropDownListFor(model => model.UserId, new SelectList(ViewData["AllEmployees"] as IEnumerable, "UserId", "DisplayName", Model.UserId)) %> 
     <%: Html.ValidationMessageFor(model => model.UserId> 
    </div>  
    </td>  
</tr>  

<tr> 
    <td> 
     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.AccessLevel)%> 
      <%: Html.RequiredMarkFor(model => model.AccessLevel)%> 
     </div> 
    </td>  
    <td>  
     <div class="editor-field"> 
      <%: Html.DropDownListFor(model => model.AccessLevel, new SelectList(ViewData["RoleList"] as IEnumerable, Model.AccessLevel))%> 
      <%: Html.ValidationMessageFor(model => model.AccessLevel)%> 
     </div>  
    </td>  
</tr> 

元數據:

[DisplayName("Employee")] 
    [Required(ErrorMessage = "Please select an employee.")] 
    [StringLength(8, ErrorMessage = "User Id must be less than 8 characters.")] 
    [DisplayFormat(ConvertEmptyStringToNull = false, 
          HtmlEncode = true)] 
    [DataType(DataType.Text)] 
    public object UserId { get; set; } 


    // Validation rules for Access Level 
    [DisplayName("Role")] 
    [Required(ErrorMessage = "Please select the role for this user.")] 
    [StringLength(15, ErrorMessage = "Role must be under 15 characters.")] 
    [DisplayFormat(ConvertEmptyStringToNull = false, 
          HtmlEncode = true)] 
    [DataType(DataType.Text)] 
    public object AccessLevel { get; set; } 

的獲取動作:

List<String> roles = (from o in txDB.Users 
             select o.AccessLevel).Distinct().ToList(); 

    var viewModel = new UserViewModel 
    { 
     User = new User(), 
     AllEmployees = empList, 
     RoleList = roles 
    }; 
    return View(viewModel); 

POST操作:

[HttpPost] 
    [AuthorizeAttribute(Roles="Administrator")] 
    public ActionResult Create(User user) 
    { 
     if(!ModelState.IsValid) 
     { 
      //ModelState is invalid 
      return View(new User()); 
     } 
     try 
     { 
      //do stuff 
     } 
    } 

所需的helper方法(從Define markup for [Required] fields in View in ASP.NET MVC 2.0):

public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) 
    { 
     if(ModelMetadata.FromLambdaExpression(expression, helper.ViewData).IsRequired) 
      return "*"; 
     else 
      return string.Empty; 
    } 

回答

2

Post方法應該如下獲得服務器端驗證...

[HttpPost] 
[AuthorizeAttribute(Roles="Administrator")] 
public ActionResult Create(User user) 
{ 
    if(!TryUpdateModel(user)) 
    { 
     // Model is INVALID 
     return View(user); 
    } 
    else 
    { 
     // ModelState is VALID 
     // Do stuff 
    } 
} 

else可能是多餘的取決於你在做什麼,但應該讓你去。 在上面的觀點你<% using Html.BeginForm() %>你需要

<% Html.EnableClientValidation(); %> 

您還需要參考腳本,MicrosoftAjax和MicrosoftMvcValidation我認爲

+0

TryUpdateModel如何參照ModelState工作?是的,所有腳本都被引用並添加了客戶端驗證,只是沒有在代碼中顯示它。 – morganpdx 2010-11-08 19:57:55

+0

好吧,我沒有看到代碼,所以我不想假設。 TryUpdateModel只是一個我堅持使用的方法,因爲有人在這裏向我推薦它。 – 2010-11-08 21:25:52

1

首先:你有兩個封閉的形式標記

如果使用

<% using (Html.BeginForm()) {%> 
<% } %> 

你不需要使用這個

<% Html.EndForm(); %> 

關於您正在使用的編輯器只爲您的用戶屬性,這是得到由模型綁定綁定

<%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%> 

嘗試與EditorForModel來代替以前的代碼的唯一一個您的驗證問題因爲您的編輯器模板適用於模型類。

所以,你的表格應

<% using (Html.BeginForm()) {%> 

    <%:Html.ValidationSummary(true) %> 
    <table> 
     <%:Html.EditorForModel()%> 
    </table> 
    <p> 
     <input type="submit" value="Add New User" /> 
    </p> 
<% } %> 

改變,你就大功告成了!

+0

只使用用戶編輯器的目的,因爲視圖使用的視圖模型爲了讓我通過兩個下拉列表。你是否建議我強烈地向用戶輸入視圖,並在viewdata中傳遞列表? – morganpdx 2010-11-08 19:23:37

+0

您的視圖很強類型化到ViewModel。您的EditorTemplate爲這兩個下拉列表創建html標記。如果你只是使用'Html.EditorFor(model => model.User ...'你告訴視圖即使你傳遞了所有的視圖模型,也只是將一個屬性綁定到視圖。 – Lorenzo 2010-11-08 19:28:18

+0

我試過了 - 效果相同。感謝您指出EndForm的冗餘,沒有注意到這一點。任何其他想法?我即將註釋掉[Required]註釋並繼續:P – morganpdx 2010-11-08 19:28:53

相關問題