ASP.Net MVC3 - why can't the default support for JSON model binding decode enumeration types?

I have a problem with ASP.Net MVC3 (RC2). I found that the new JSON model binding function, which is implicit in MVC3, does not want to deserialize an enumeration type property.

Here is an example of a class and enumeration type:

public enum MyEnum { Nothing = 0, SomeValue = 5 }
public class MyClass
{
    public MyEnum Value { get; set; }
    public string OtherValue { get; set; }
}

Consider the following code that successfully passes the unit test:

[TestMethod]
public void Test()
{
    var jss = new JavaScriptSerializer();
    var obj1 = new MyClass { Value = MyEnum.SomeValue };
    var json = jss.Serialize(obj1);
    var obj2 = jss.Deserialize<MyClass>(json);
    Assert.AreEqual(obj1.Value, obj2.Value);
}

If I serialize obj1above, but then send this data to the MVC3 controller (example below) with a single parameter of type MyClass, any other properties of object deserialization properly, but any property that is an enumeration type, will deserialize to the default value (zero).

[HttpPost]
public ActionResult TestAction(MyClass data)
{
    return Content(data.Value.ToString()); // displays "Nothing"
}

MVC codeplex, , , , , , Microsoft , , , - .

.

+5
2

. , RTM MVC3, , , JsonValueProviderFactory, JavaScriptSerializer . DeserializeObject(), . , / int, .

ASP.Net:
http://forums.asp.net/p/1622895/4180989.aspx

, , :

public class EnumConverterModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        var propertyType = propertyDescriptor.PropertyType;
        if(propertyType.IsEnum)
        {
            var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if(null != providerValue)
            {
                var value = providerValue.RawValue;
                if(null != value)
                {
                    var valueType = value.GetType();
                    if(!valueType.IsEnum)
                    {
                        return Enum.ToObject(propertyType, value);
                    }
                }
            }
        }
        return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
    }
}

Application_Start :

ModelBinders.Binders.DefaultBinder = new EnumConverterModelBinder();
+9

? :

$.post(
    '/TestAction', 
    JSON.stringify({ OtherValue : 'foo', Value: 5 }), 
    function(result) {
        alert('ok');
    }
);
0

All Articles