开发者

ModelBinding enum values for selectlist and selected item

Ok, this was supposed to be a question asking for help getting my form to work properly. In the process of creating an example to post, I figured out what the fix is.

So now it's a become a question about why it works one way and not the other. I really cannot understand the behaviour. Have I found a bug in MVC? Or is there something I don't understand about html requests which makes this behaviour correct?

The example invloves setting the selected value in a dropdown through an enum property in a view model which is bound from the querystring (it's probaly clearer what I'm talking about if you just read the code):

Controller/Model

public class HomeController : Controller
{
    public ActionResult Index(TestModel model)
    {
        return View(model);
    }
}

public class TestModel
{
    public SelectList EnumOptions { get; set; }
    public TestEnum EnumValue { get; set; }

    public TestModel()
    {
        var options =  from Enum e in Enum.GetValues(typeof(TestEnum))
                         select new { Value = e, Name = e.ToString() };

        EnumOptions = new SelectList(options, "Value", "Name", TestEnum.NotSet);
    }
}

public enum TestEnum
{
    NotSet = 0,
    Dog = 1,
    Cat = 2
} 

View

@Html.DropDownListFor(m => m.EnumValue, Model.EnumOptions)

<a href="?EnumValue=Dog">Dog numeric</a>
<a href="?EnumValue=1">Dog string</a>

It's all pretty simple.

The question is, why doesn't the second "Dog" link work properly? Note it submits the enumVa开发者_开发知识库lue as a numeric property, instead of as a "string" property.

But the model binder has no problem with this. The model supplied to the View is exactly the same in either case. So how does the dropdown selected value get rendered correctly in one case but not the other?


DropDownListFor looks into the modelstatedictionary for getting the current value of the field/property. The ValueProviderResult for the second link has a value from 1.

The modelbinder knows that the requested type is a TestEnum. A 1 can be converted to Dog. The dropwdownlist converts the value of the ValueProviderResult into a string. A 1 converts to "1" as a string. There is no entry in the selectlist with a value of "1".

Therefor the dropdownlist has a wrong current value.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜