Question

I have created an editor template for representing selecting from a dynamic dropdown list and it works as it should except for validation, which I have been unable to figure out. If the model has the [Required] attribute set, I want that to invalidate if the default option is selected.

The view model object that must be represented as the dropdown list is Selector:

public class Selector
{
    public int SelectedId { get; set; }
    public IEnumerable<Pair<int, string>> Choices { get; private set; }
    public string DefaultValue { get; set; }

    public Selector()
    {
        //For binding the object on Post
    }

    public Selector(IEnumerable<Pair<int, string>> choices, string defaultValue)
    {
        DefaultValue = defaultValue;
        Choices = choices;
    }
}

The editor template looks like this:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<select class="template-selector" id="<%= ViewData.ModelMetadata.PropertyName %>.SelectedId" name="<%= ViewData.ModelMetadata.PropertyName %>.SelectedId">
<%
    var model = ViewData.ModelMetadata.Model as QASW.Web.Mvc.Selector;
    if (model != null)
    {
            %>
    <option><%= model.DefaultValue %></option><%
        foreach (var choice in model.Choices)
        {
            %>
    <option value="<%= choice.Value1 %>"><%= choice.Value2 %></option><%
        }
    }
     %>
</select>

I sort of got it to work by calling it from the view like this (where Category is a Selector):

<%= Html.ValidationMessageFor(n => n.Category.SelectedId)%>

But it shows the validation error for not supplying a proper number and it does not care if I set the Required attribute.

Was it helpful?

Solution

I found a solution where validation is done against hidden fields using custom validation rules, here. Using this approach you can easily add custom validation to arbitrary types.

OTHER TIPS

Why is not your editor template strongly typed?

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<QASW.Web.Mvc.Selector>" %>

Why not use the DropDownListFor helper:

<%= Html.DropDownListFor(
    x => x.SelectedId, 
    new SelectList(Model.Choices, "Value1", "Value2")
)%>

To avoid the magic strings you could add a ChoicesList property to your view model:

public IEnumerable<SelectListItem> ChoicesList 
{
    get
    {
        return Choices.Select(x => new SelectListItem
        {
            Value = x.Value1.ToString(),
            Text = x.Value2
        });
    }
}

and bind your helper to it:

<%= Html.DropDownListFor(x => x.SelectedId, Model.ChoicesList) %>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top