2009-09-01 168 views
2

我一直在嘗試遵循Web上的驗證教程和示例,例如David Hayden's Blog和官方ASP.Net MVC Tutorials,但我無法獲取以下代碼顯示實際的驗證錯誤。如果我有一個看起來是這樣的一個觀點:ASP.NET MVC:在TryUpdateModel中設置的驗證消息未顯示ValidationSummary

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.Parent>" %> 

<%-- ... content stuff ... --%> 

<%= Html.ValidationSummary("Edit was unsuccessful. Correct errors and retry.") %> 
<% using (Html.BeginForm()) {%> 

<%-- ... "Parent" editor form stuff... --%> 

     <p> 
      <label for="Age">Age:</label> 
      <%= Html.TextBox("Age", Model.Age)%> 
      <%= Html.ValidationMessage("Age", "*")%> 
     </p> 

<%-- etc... --%> 

對於一個模型類,看起來像這樣:

public class Parent 
{ 
    public String FirstName { get; set; } 
    public String LastName { get; set; } 
    public int Age { get; set; } 
    public int Id { get; set; } 
} 

每當我進入一個無效的年齡(因爲年齡被聲明爲int)如「xxx」(非整數),視圖確實在屏幕頂部正確顯示消息「編輯失敗,更正錯誤並重試」,以及突出顯示Age文本框並放置一個紅色星號在它旁邊,指出錯誤。但是,沒有錯誤消息列表與ValidationSummary一起顯示。當我做我自己的驗證(例如:對於下面的LastName)時,消息顯示正確,但當字段具有非法值時,TryUpdateModel的內置驗證似乎不會顯示消息。

這裏是行動在我的控制器代碼中調用:

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult EditParent(int id, FormCollection collection) 
    { 
     // Get an updated version of the Parent from the repository: 
     Parent currentParent = theParentService.Read(id); 

     // Exclude database "Id" from the update: 
     TryUpdateModel(currentParent, null, null, new string[]{"Id"}); 
     if (String.IsNullOrEmpty(currentParent.LastName)) 
      ModelState.AddModelError("LastName", "Last name can't be empty."); 
     if (!ModelState.IsValid) 
      return View(currentParent); 

     theParentService.Update(currentParent); 
     return View(currentParent); 
    } 

我錯過了什麼?

回答

2

我下載了,看着ASP.NET MVC v1.0 source code來自微軟,並發現,無論是偶然的還是,沒有辦法做我想做的事情,至少在默認情況下。顯然,在調用UpdateModel或TryUpdateModel期間,如果對整數(例如)的驗證失敗,則在與ModelState關聯的ModelError中爲Error值顯式設置ErrorMessage,但設置Exception屬性。據來自MVC ValidationExtensions的代碼,下面的代碼被用於獲取錯誤文本:

string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */); 

通知的ModelState中的空參數傳遞。該GetUserErrorMEssageOrDefault方法則是這樣開始的:

private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState) { 
    if (!String.IsNullOrEmpty(error.ErrorMessage)) { 
     return error.ErrorMessage; 
    } 
    if (modelState == null) { 
     return null; 
    } 

    // Remaining code to fetch displayed string value... 
} 

所以,如果ModelError.ErrorMessage屬性爲空(我證實,這是試圖將一個非整數值設置爲一個申報INT時),MVC的推移檢查我們已經發現的ModelState爲null,因此返回任何Exception ModelError的null。所以,在這一點上,我的2個最佳工作周圍的想法對這個問題有:

  1. 創建一個自定義的驗證擴展,它可以正確地返回時,未設置的ErrorMessage合適的消息,但例外的是設定。
  2. 如果ModelState.IsValid返回false,則創建在控制器中調用的預處理函數。預處理函數將在沒有設置ErrorMessage的ModelState中查找值,但設置了Exception,然後使用ModelState.Value.AttemptedValue派生適當的消息。

還有其他想法嗎?

+1

我自己也來到了這個相同的實現,但通過一些小小的嘗試和錯誤。你的#2大概是我最終不得不做的。 – Funka 2009-09-01 18:59:34

+0

你知道在MVC3中是否有這樣做的方法?我即將創建一個全局動作過濾器,從我的異常複製到ErrorMessage屬性,但似乎很奇怪,我應該! – mcintyre321 2011-09-26 14:13:07