Reputation: 1507
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>
}
Upvotes: 2
Views: 4080
Reputation: 1038810
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.
Upvotes: 8