ASP.NET MVC:在TryUpdateModel中设置的验证消息未显示ValidationSummary

时间:2009-09-01 13:16:59

标签: c# asp.net-mvc validationsummary

我一直在尝试关注网络上的验证教程和示例,例如来自David Hayden's Blog和官方ASP.Net MVC Tutorials,但我无法获得以下代码来显示实际验证错误。如果我的视图看起来像这样:

<%@ 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; }
}

每当我输入无效年龄(因为Age被声明为int)时,例如“xxx”(非整数),视图 会正确显示消息“编辑失败。正确“错误并重试”在屏幕顶部,以及突出显示“年龄”文本框并在其旁边放置一个红色星号,表示错误。但是,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);
    }

我错过了什么?

1 个答案:

答案 0 :(得分:2)

我下载并查看了Microsoft的ASP.NET MVC v1.0 source code,发现无论是偶然还是设计,都无法做到我想做的事情,至少在默认情况下如此。显然,在调用UpdateModel或TryUpdateModel期间,如果整数(例如)的验证失败,则在与ModelState关联的ModelError中未显式设置ErrorMessage以获取错误值,而是设置Exception属性。根据MVC ValidationExtensions中的代码,以下代码用于获取错误文本:

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

请注意,传递了modelState的null参数。 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时正确返回相应的消息,但设置了Exception。
  2. 如果ModelState.IsValid返回false,则创建在控制器中调用的预处理函数。预处理函数将在ModelState中查找未设置ErrorMessage的值,但设置了Exception,然后使用ModelState.Value.AttemptedValue派生相应的消息。
  3. 还有其他想法吗?