I'm trying to use the built in ASP.NET MVC 2 client side validation on a Select List like the following:
 private SelectList _CategoryList;
        [Required(ErrorMessage = "Category Required")]
        [System.ComponentModel.DataAnnotations.Range(1, double.MaxValue, ErrorMessage = "Please Select A Category")]
        [DisplayName("Category")]
        public SelectList CategoryList
        {
            get
            {
                return new SelectList(Categories, "CatID", "CatFullName"); ;
            }
            set
            {
                _CategoryList = value;
            }
        }
However it's not working...if the default value which is 0 is selected the validation message does not appear and the page progresses as though it's validated. Thoughts?
In ASP.NET MVC, Data Annotation is used for data validation for developing web-based applications. We can quickly apply validation with the help of data annotation attribute classes over model classes.
ComponentModel. DataAnnotations namespace includes the following validator attributes: Range – Enables you to validate whether the value of a property falls between a specified range of values. RegularExpression – Enables you to validate whether the value of a property matches a specified regular expression pattern.
In ASP.NET MVC application we can do the Server Side Validation on the Model using Data Annotations. Data Annotations is a namespace that provides attribute classes, and these classes define metadata for controls. In MVC we decorate Model Properties with these attribute classes to provide metadata.
Ok so I found the answer in an answer to a slightly different question. So I'm posting my complete code here, which extends on Scott Guthries ASP.NET MVC 2 Validation post: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx
My ViewModel:
public class Person
{
    [Required(ErrorMessage="First Name Required")]
    [StringLength(50,ErrorMessage="Must be under 50 characters")]
    public string FirstName { get; set; }
    [Required(ErrorMessage="Last Name Required")]
    [StringLength(50, ErrorMessage = "Must be under 50 characters")]
    public string LastName { get; set; }
    [Required(ErrorMessage="Age Required")]
    [Range(1,120,ErrorMessage="Age Must be between 0 and 120")]
    public int Age { get; set; }
    [Required(ErrorMessage="Email Required")]
    public string Email { get; set; }
    public IEnumerable<SelectListItem> FavoriteColor { get; set; }
    [Range(0, 6, ErrorMessage = "Out of range")]
    public int SelectedFavColor { get; set; }
}
My Color class:
public class Colors
{
    public int ColorID { get; set; }
    public string ColorName { get; set; }
}
My list helper extensions stolen from Rob Connery, who stole it from someone else:
public static class ListExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach (var item in collection) action(item);
        return collection;
    }
    public static SelectList ToSelectList<T>(this IEnumerable<T> collection)
    {
        return new SelectList(collection, "Key", "Value");
    }
    public static SelectList ToSelectList<T>(this IEnumerable<T> collection, string selectedValue)
    {
        return new SelectList(collection, "Key", "Value", selectedValue);
    }
    public static SelectList ToSelectList<T>(this IEnumerable<T> collection,
                         string dataValueField, string dataTextField)
    {
        return new SelectList(collection, dataValueField, dataTextField);
    }
    public static SelectList ToSelectList<T>(this IEnumerable<T> collection,
                         string dataValueField, string dataTextField, string selectedValue)
    {
        return new SelectList(collection, dataValueField, dataTextField, selectedValue);
    }
}
My Controller Code (yes it could be refactored to be more DRY):
public ActionResult Create()
    {
        Person newFriend = new Person();
        IList<Colors> colorslist = new List<Colors>();
        colorslist.Add(new Colors { ColorID = -1, ColorName = "Please Select Color" });
        colorslist.Add(new Colors { ColorID = 1, ColorName = "Red" });
        colorslist.Add(new Colors { ColorID = 2, ColorName = "Green" });
        colorslist.Add(new Colors { ColorID = 3, ColorName = "Blue" });
        newFriend.FavoriteColor = colorslist.ToSelectList("ColorID","ColorName","-1");
        return View(newFriend);
    }
    [HttpPost]
    public ActionResult Create(Person friendToCreate, FormCollection collection)
    {
        friendToCreate.SelectedFavColor = Convert.ToInt32(collection["SelectedFavColor"]);
        if (ModelState.IsValid)
        {
            return Redirect("/");
        }
        IList<Colors> colorslist = new List<Colors>();
        colorslist.Add(new Colors { ColorID = -1, ColorName = "Please Select Color" });
        colorslist.Add(new Colors { ColorID = 1, ColorName = "Red" });
        colorslist.Add(new Colors { ColorID = 2, ColorName = "Green" });
        colorslist.Add(new Colors { ColorID = 3, ColorName = "Blue" });
        friendToCreate.FavoriteColor = colorslist.ToSelectList("ColorID", "ColorName");
        return View(friendToCreate);
    }
My page markup:
<% using (Html.BeginForm()) {%>
    <fieldset>
        <legend>Fields</legend>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.FirstName) %>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.FirstName) %>
            <%= Html.ValidationMessageFor(model => model.FirstName) %>
        </div>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.LastName) %>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.LastName) %>
            <%= Html.ValidationMessageFor(model => model.LastName) %>
        </div>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.Age) %>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.Age) %>
            <%= Html.ValidationMessageFor(model => model.Age) %>
        </div>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.Email) %>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.Email) %>
            <%= Html.ValidationMessageFor(model => model.Email) %>
        </div>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.FavoriteColor) %>
        </div>
        <div class="editor-field">
            <%= Html.DropDownList("SelectedFavColor", Model.FavoriteColor, -1)%>
            <%= Html.ValidationMessageFor(model => model.SelectedFavColor) %>
        </div>
        <p>
            <input type="submit" value="Submit" />
        </p>
    </fieldset>
<% } %>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With