I have a view model:
public class RegisterModel
{
...
public bool Confirmation{ get; set; }
}
I use checkbox helper on my view:
@model RegisterModel
......
@Html.CheckBoxFor(m => m.Confirmation)
This checkbox html helper creates:
<input id="Confirmation" name="Confirmation" value="true" type="checkbox">
<input name="Confirmation" value="false" type="hidden">
On Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (!ModelState.IsValid)
return View(model);
.....
}
Let's say some user changes values of inputs to 'xxx' and posts it. Therefore, Model is not valid and we return view. After that, Html.CheckBoxFor gives this error:
The parameter conversion from type 'System.String' to type 'System.Boolean' failed.
Inner Exception:
System.FormatException: xxx is not a valid value for Boolean
When we return view: Model.Confirmation value is false but Request["Confirmation"] value is 'xxx'.
This error comes from ValueProviderResult class on ConvertSimpleType method. I think, it tries to convert Request["Confirmation"] value to boolean and it gives error.
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Conversion failure is not fatal")]
private static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType)
{
.....
TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
bool canConvertFrom = converter.CanConvertFrom(value.GetType());
if (!canConvertFrom)
{
converter = TypeDescriptor.GetConverter(value.GetType());
}
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{
// EnumConverter cannot convert integer, so we verify manually
if (destinationType.IsEnum && value is int)
{
return Enum.ToObject(destinationType, (int)value);
}
string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_NoConverterExists,
value.GetType().FullName, destinationType.FullName);
throw new InvalidOperationException(message);
}
.....
}
How can I fix or avoid this error?
CheckBoxForcreate two inputs with exactly same name?ModelState.IsValue == false?if (!ModelState.IsValid) { bool confirmation = bool.TryParse(Request["Confirmation"],out confirmation); ModelState.Remove("Confirmation"); request.Confirmation = confirmation; return View(request); }But I dunno why helper tries to get value from request beside of model.Falseto be posted, a malicious user must be manipulating the value of the hidden input (e.g. posting a value using fiddler in order to try and cause you app to fail). So why not just redirect them to an error page telling them to ....