I've got the following model class (stripped for simplicity):
public class Info
{
public int IntData { get; set; }
}
Here's my Razor form that uses this model:
@model Info
@Html.ValidationSummary()
@using (Html.BeginForm())
{
@Html.TextBoxFor(x => x.IntData)
<input type="submit" />
}
Now if I enter a non-numeric data into the textbox, I receive a correct validation message, i.e.: "Value 'qqqqq' is not valid for field 'IntData'".
But if I enter a very long sequence of digits (like 345234775637544), I receive an EMPTY validation summary.
In my controller code, I see that ModelState.IsValid
is false
as expected, and ModelState["IntData"].Errors[0]
is as follows:
{System.Web.Mvc.ModelError}
ErrorMessage: ""
Exception: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."}
(exception itself) [System.InvalidOperationException]: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."}
InnerException: {"345234775637544 is not a valid value for Int32."}
As you can see, the validation works normally, but doesn't yield an error message to the user.
Can I tweak the default model binder's behavior so that it shows a proper error message in this case? Or will I have to write a custom binder?
One way would be to write a custom model binder:
public class IntModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value != null)
{
int temp;
if (!int.TryParse(value.AttemptedValue, out temp))
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format("The value '{0}' is not valid for {1}.", value.AttemptedValue, bindingContext.ModelName));
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
}
return temp;
}
return base.BindModel(controllerContext, bindingContext);
}
}
which could be registered in Application_Start
:
ModelBinders.Binders.Add(typeof(int), new IntModelBinder());
How about setting MaxLength on the input field to 10 or so? I would do that in combination with setting a range on IntData. Unless of course you want allow a user to enter 345234775637544. In that case you're better off with a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With