I have a model binder for a custom type Money
. The binder works fine, but the built in binding/validation is kicking in and marking data as invalid.
My binder looks like this:
public class MoneyModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var money = (Money)bindingContext.Model;
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Amount").AttemptedValue;
var currencyCode = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Iso3LetterCode").AttemptedValue;
Money parsedValue;
if (String.IsNullOrEmpty(value))
{
money.Amount = null;
return;
}
var currency = Currency.FromIso3LetterCode(currencyCode);
if(!Money.TryParse(value, currency, out parsedValue))
{
bindingContext.ModelState.AddModelError("Amount", string.Format("Unable to parse {0} as money", value));
}
else
{
money.Amount = parsedValue.Amount;
money.Currency = parsedValue.Currency;
}
}
}
When a user types a value like "45,000" into a textbox my binder correctly picks up the value, parses it and sets it into the model.
The problem I have, is that the default validation then kicks in a states The value '45,000' is not valid for Amount
, which as it's a decimal type makes sense, but I've already bound the data. How can I prevent the default binders binding data which I've already handled?
I'm not sure if this make any difference, but I'm using Html.EditorFor
with and editor that looks like this:
@model Money
<div class="input-prepend">
<span class="add-on">@Model.Currency.Symbol</span>
@Html.TextBoxFor(m => m.Amount, new{
placeholder=string.Format("{0}", Model.Currency),
@class="input-mini",
Value=String.Format("{0:n0}", Model.Amount)
})
@Html.HiddenFor(x => x.Iso3LetterCode)
</div>