views:

376

answers:

2

The model validation doesn't evaluates the attributes linked to listbox values if you don't select at least one of them. This way is not possible to do a model evaluation using DataAnnotations in order to inform required values.

The controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestValidation.Models;

namespace TestValidation.Controllers
{
  [HandleError]
  public class HomeController : Controller
  {
    private SelectList list = new SelectList(new List<string>()
        {
            "Sao Paulo",
            "Toronto",
            "New York",
            "Vancouver"
        });
    public ActionResult Index()
    {
      ViewData["ModelState"] = "NOT EVAL";
      ViewData["ItemsList"] = list;
      return View();
    }
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(MyEntity entity)
    {
      if (ModelState.IsValid)
      {
        ViewData["ModelState"] = "VALID";
      }
      else
      {
        ViewData["ModelState"] = "NOT VALID!!!";
      }
      ViewData["ItemsList"] = list;
      return View();
    }

    public ActionResult About()
    {
      return View();
    }

  }
}

The View:

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

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
  Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
  <h2>
    Validation Test</h2>
  <p>
  <% using (Html.BeginForm())
     {%>
  <fieldset>
    <p>
      ModelState:
      <%= Html.Encode((string)ViewData["ModelState"])%>
    </p>
    <p>
      <label for="Name">
        Name:</label>
      <%= Html.TextBoxFor(m => m.Name)%>
      <%= Html.ValidationMessageFor(m => m.Name)%>
    </p>
    <p>
      <label for="ItemFromList">
        Items (list):</label>
      <%= Html.ListBoxFor(m => m.ItemFromList, ViewData["ItemsList"] as SelectList)%>
      <%= Html.ValidationMessageFor(m => m.ItemFromList)%>
    </p>
    <p>
      <label for="ItemFromCombo">
        Items (combo):</label>
      <%= Html.DropDownListFor(m => m.ItemFromCombo, ViewData["ItemsList"] as SelectList)%>
      <%= Html.ValidationMessageFor(m => m.ItemFromCombo)%>
    </p>
    <p>
      <input type="submit" value="Submit" />
    </p>
  </fieldset>
  <% } %>
</asp:Content>

The Model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;


namespace TestValidation.Models
{
  public class MyEntity_Validate : ValidationAttribute
  {
    public MyEntity_Validate()
    {
      this.ErrorMessage = "Validated!. Is <> Toronto";
    }
    public override bool IsValid(object value)
    {
      return ((string)value == "Toronto");
    } 
  }
  public class MyEntity
  {
    [Required]
    public string Name { get; set; }
    [MyEntity_Validate]
    public string ItemFromList { get; set; }
    [MyEntity_Validate]
    public string ItemFromCombo { get; set; }
  }
}

Any help would be very much appreciated. Thank you.

A: 

The issue is known, but the MVC development team does not currently have plans to change the functionality (http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=4858).

spmason blog post: http://spmason.com/post/343293206/why-aspnetmvc-2-is-broken

Personally, I agree with you that the functionality is confusing. If a field is required and not passed in, then the ModelState is invalid.

smaglio81
Good News! Scott Gu has stated "Team is looking at changing behavior for final ASP.NET MVC 2 release to validate all properties by default".http://twitter.com/scottgu/statuses/8057127000
smaglio81
A: 

Really good news!

in VS2010 RC is necessary to update the version of ASP.NET MVC. Please, check this: http://www.nitrix-reloaded.com/2010/03/15/install-asp-net-mvc-2-rtm-on-vs2010-rc/

Jorge