カスタムタイプのモデルバインダーがありますMoney
。バインダーは正常に機能しますが、組み込みのバインディング/検証が開始され、データが無効としてマークされます。
私のバインダーは次のようになります:
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;
}
}
}
ユーザーが「45,000」などの値をテキストボックスに入力すると、バインダーはその値を正しく取得し、解析してモデルに設定します。
私が抱えている問題は、デフォルトの検証が状態The value '45,000' is not valid for Amount
で開始されることです。これは10進型であるため意味がありますが、データはすでにバインドされています。すでに処理したデータをバインドするデフォルトのバインダーを防ぐにはどうすればよいですか?
これが違いを生むかどうかはわかりませんがHtml.EditorFor
、次のようなエディターを使用しています。
@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>