Barry Franklin
Barry Franklin

Reputation: 1820

Bind to object's property with EnumDropDownListFor

I am wanting to use the @Html.EnumDropDownListFor and I'm having an issue.

This is what I have:

@Html.EnumDropDownListFor(x => x.DefaultProviderEnum, 
               "Select default provider", new { @class = "form-control", id = "pro" })

Where DefaultProviderEnum is of type ProviderFormat:

public enum ProviderFormat
{
    [Description("ASG")]
    ASG = 1,
    [Description("SCS")]
    SCS = 2
}

And I set it correctly in the model and it appears correctly when it loads. The issue that I have is when I post it I have to manually set it in my object instead of it binding to a property on my object, which is an int:

 model.CU.DefaultProviderInt = (int)model.DefaultProviderEnum;

Is there a way to bind the enum drop down to a property on an object and not have to set it this way?

Upvotes: 0

Views: 317

Answers (2)

adiga
adiga

Reputation: 35222

model.CU object will also get bound (binded?) by the ModeBinder with whatever value has been provided on submit of the form.

So, in your form, you can have a hidden property like this:

@Html.HiddenFor(x => x.CU.DefaultProviderInt, new { id = "cu-default-provider" })

Then add a change event handler to the DefaultProviderEnum dropdown and set hidden input's value with the select value.

$(function() {
    $("#DefaultProviderEnum").change(function(){
        $("#cu-default-provider").val($(this).val());
    })
});

Now when the form gets submitted, both the properties will have the same value.


There's another way to do this. The above code won't work if you manually set the value of DefaultProviderEnum somewhere in your code. So, you can have a custom setter for the DefaultProviderEnum property:

private ProviderFormat defaultProviderEnum;

public ProviderFormat DefaultProviderEnum
{
    get { return defaultProviderEnum; }
    set
    {
        if (this.CU != null)
        {
            this.CU.DefaultProviderInt = (int)value;
        }

        defaultProviderEnum = value;
    }
}

But, this also might depend on the order in which DefaultModelBinder binds properties. (If CU is null when DefaultProviderEnum is being set, then this might not work. So make sure to init CU in model's constructor)


The third and the best way to do this is to manually cast the enum to int and set it to CU.DefaultProviderInt.

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239270

What's wrong with what you have? If the field is bound to DefaultProviderEnum, then that's the only thing that will be set by the modelbinder, anyways, so some manual intervention would be required to set a different property based on that. There's no way to have the modelbinder set two properties based on one posted value, if that's the tree you're barking up.

However, you can simply have a property like:

public int DefaultProviderInt => (int)DefaultProviderEnum;

Then, it will always just return the int coercion of the enum's value, whatever that happens to be at the moment.

Upvotes: 1

Related Questions