ASP.NET MVC: Validation messages set in TryUpdateModel not showning ValidationSummary

為{幸葍}努か 提交于 2019-12-24 01:44:29

问题


I've been trying to follow the validation tutorials and examples on the web, such as from David Hayden's Blog and the official ASP.Net MVC Tutorials, but I can't get the below code to display the actual validation errors. If I have a view that looks something like this:

<%@ 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... --%>

For a model class that looks like this:

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

Whenever I enter an invalid Age (since Age is declared as an int), such as "xxx" (non-integer), the view does correctly display the message "Edit was unsuccessful. Correct errors and retry" at the top of the screen, as well as highlighting the Age text box and put a red asterisk next to it, indicating the error. However, no list of error messages is displayed with the ValidationSummary. When I do my own validation (e.g.: for LastName below), the message displays correctly, but the built-in validation of TryUpdateModel does not seem to display a message when a field has an illegal value.

Here is the action invoked in my controller code:

    [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);
    }

What did I miss?


回答1:


I downloaded and looked at the ASP.NET MVC v1.0 source code from Microsoft, and discovered that, either by accident or by design, there isn't a way to do what I want to do, at least by default. Apparently during a call to UpdateModel or TryUpdateModel, if validation of an integer (for example) fails, an ErrorMessage is not explicitly set in the ModelError associated with the ModelState for the bad value, but instead the Exception property is set. According to the code from the MVC ValidationExtensions, the following code is used to fetch the error text:

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

Notice the null parameter for the modelState is passed. The GetUserErrorMEssageOrDefault method then begins like this:

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...
}

So, if the ModelError.ErrorMessage property is empty (which I verified that it is when trying to set a non-integer value to a declared int), MVC goes on to check the ModelState, which we already discovered is null, thus null is returned for any Exception ModelError. So, at this point, my 2 best work-around ideas to this issue are:

  1. Create a custom Validation extension that correctly returns an appropriate message when ErrorMessage is not set, but Exception is set.
  2. Create a pre-processing function that is called in the controller if ModelState.IsValid returns false. The pre-processing function would look for values in the ModelState where the ErrorMessage is not set, but the Exception is set, and then derive an appropriate message using the ModelState.Value.AttemptedValue.

Any other ideas?



来源:https://stackoverflow.com/questions/1362435/asp-net-mvc-validation-messages-set-in-tryupdatemodel-not-showning-validationsu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!