Using checkboxes to PostBack Enum with Flags

有些话、适合烂在心里 提交于 2019-12-03 03:15:39
Erwin Rooijakkers

If you check the POST body the data is sent, it is just not picked up properly. This is because MVC is not handling flags enumerations well. Someone who answered a similar question describes this:

In general I avoid using enums when designing my view models because they don't play with ASP.NET MVC's helpers and out of the box model binder. They are perfectly fine in your domain models but for view models you could use other types.

There the person answering the question also provides a full answer to how to bind a flags enumeration anyway. What you basically need to do is create your own custom model binder that can handle flags enumeration. In another post called ASP.Net MVC Flag Enumeration Model Binder I found an example and I will copy the relevant code.

Add a class called CustomModelBinder as follows:

public class CustomModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(
        ControllerContext controllerContext, 
        ModelBindingContext bindingContext, 
        PropertyDescriptor propertyDescriptor, 
        IModelBinder propertyBinder)
    {
        var propertyType = propertyDescriptor.PropertyType;

        // Check if the property type is an enum with the flag attribute
        if (propertyType.IsEnum && propertyType.GetCustomAttributes(true).Any())
        {
            var providerValue = bindingContext.ValueProvider
                .GetValue(bindingContext.ModelName);
            if (providerValue != null)
            {
                var value = providerValue.RawValue;
                if (value != null)
                {
                    // In case it is a checkbox list/dropdownlist/radio 
                    // button list
                    if (value is string[])
                    {
                        // Create flag value from posted values
                        var flagValue = ((string[])value)
                            .Aggregate(0, (acc, i) 
                                => acc | (int)Enum.Parse(propertyType, i));

                        return Enum.ToObject(propertyType, flagValue);
                    }

                    // In case it is a single value
                    if (value.GetType().IsEnum)
                    {
                        return Enum.ToObject(propertyType, value);
                    }
                }
            }
        }

        return base.GetPropertyValue(controllerContext, 
            bindingContext, 
            propertyDescriptor, 
            propertyBinder);
    }
}

Then in the Global.asax.cs Application_Start method register the custom model binder as follows:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    // Register custom flag enum model binder
    ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
}

This should work.

Source: http://itq.nl/asp-net-mvc-flag-enumeration-model-binder/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!