Asp.net mvc 4 Model binder ValueProvider appends to the existing value + MVC 4

Asp.net mvc 4 Model binder ValueProvider appends to the existing value + MVC 4,asp.net-mvc-4,razor,Asp.net Mvc 4,Razor,I have the below method in my model binder: protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { if (bindingContext.ValueProvider.GetValue("Id") == null) { string s = bindingContext.ValueProvider.GetValue("IsSoftDeleted").AttemptedValue; bool d = Convert.ToBoolean(s); return OrgFactory.Create(bindingContext.ValueProvider.GetValue("Caption").AttemptedValue,

I have the below method in my model binder:

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        if (bindingContext.ValueProvider.GetValue("Id") == null)
        {
            string s = bindingContext.ValueProvider.GetValue("IsSoftDeleted").AttemptedValue;

            bool d = Convert.ToBoolean(s);
            return OrgFactory.Create(bindingContext.ValueProvider.GetValue("Caption").AttemptedValue,
                            bindingContext.ValueProvider.GetValue("NameInUse").AttemptedValue,
                            bindingContext.ValueProvider.GetValue("Description").AttemptedValue,
                            d, new Party());
        }
        else
        {
            return OrgFactory.Create(bindingContext.ValueProvider.GetValue("Caption").AttemptedValue,
                            bindingContext.ValueProvider.GetValue("NameInUse").AttemptedValue,
                            bindingContext.ValueProvider.GetValue("Description").AttemptedValue, 
                            Convert.ToBoolean(bindingContext.ValueProvider.GetValue("IsSoftDeleted").AttemptedValue));
        }
    }

in create.cshtml view, if I check the chebox for IsSoftDeleted, its value in model binder is coming as "true,false" when it should come only true.

Can u advise what I am doing wrong?

create.cshtml

@using PartyBiz.Models.Objects
@model Organization

@using (Html.BeginForm("Create", "Organization", FormMethod.Post))
{

@Html.ValidationSummary(true)
<fieldset>
    <legend>Create a New Organization</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Caption) 
        @Html.EditorFor(model => model.Caption, new { @class = "txt"}) 
        @Html.ValidationMessageFor(model => model.Caption) 
    </div> <br />

    <div class="editor-label">
        @Html.LabelFor(model => model.NameInUse)
        @Html.EditorFor(model => model.NameInUse, new { @class = "txt"}) 
        @Html.ValidationMessageFor(model => model.NameInUse)
    </div> <br />

    <div class="editor-label">
        @Html.LabelFor(model => model.Description)
        @Html.EditorFor(model => model.Description, new { @class = "txt"}) 
        @Html.ValidationMessageFor(model => model.Description)
    </div> 
    <div class="editor-label">
        @Html.LabelFor(O => O.IsSoftDeleted)
        @Html.EditorFor(O => O.IsSoftDeleted)
        @Html.ValidationMessageFor(O => O.IsSoftDeleted)
    </div>
    <br />
        <input type="submit" value="Create" />
</fieldset>
}  

#1

You are attempting to parse the string value of true,false to a boolean using the Convert.ToBoolean method which will more than obviously fail. The correct way to deal with this situation is to simply use what's already built into the framework => use the ConvertTo method on the ValueProviderResult that will be returned by the GetValue method.

Just like that:

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
    ValueProviderResult isSoftDeletedValue = bindingContext.ValueProvider.GetValue("IsSoftDeleted");
    // use the built-in method into the model binder to correctly convert
    // the value to the corresponding boolean type 
    bool isSoftDeleted = (bool)isSoftDeletedValue.ConvertTo(typeof(bool));

    if (bindingContext.ValueProvider.GetValue("Id") == null)
    {

        return OrgFactory.Create(
            bindingContext.ValueProvider.GetValue("Caption").AttemptedValue,
            bindingContext.ValueProvider.GetValue("NameInUse").AttemptedValue,
            bindingContext.ValueProvider.GetValue("Description").AttemptedValue,
            isSoftDeleted, 
            new Party()
        );
    }

    return OrgFactory.Create(
        bindingContext.ValueProvider.GetValue("Caption").AttemptedValue,
        bindingContext.ValueProvider.GetValue("NameInUse").AttemptedValue,
        bindingContext.ValueProvider.GetValue("Description").AttemptedValue, 
        isSoftDeleted
    );
}

That's it:

var isSoftDeletedValue = bindingContext.ValueProvider.GetValue("IsSoftDeleted");
bool isSoftDeleted = (bool)isSoftDeletedValue.ConvertTo(typeof(bool));

Notice that here we are calling the underlying ConvertTo method on the ValueProviderResult which knows how to correctly handle the situation.


#2

possible duplicate of Why Html.Checkbox("Visible") returns "true, false" in ASP.NET MVC 2?

#3

How to handle this scenario for LIST OF CHECKBOXES with same name. and to get all the checked values.

#4

I have a checkbox and I get 'on' as a value from the ValueProvider. So ConvertTo() throws also. Go figure...

#5

OK. I have added a second hidden input just like ASP MVC does and it got fixed. Stupid web tech...