I'm using Steve Sandersons BeginCollectionItem
extension to help with binding lists of items. This works fine for primitive types. The problem I'm having is that for a custom model binder that I've written I can't see how to generate the full name and index of the item that I'm binding to.
Currently my model binder looks like this:
public class MoneyModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Amount");
if (valueResult != null)
{
var value = valueResult.AttemptedValue;
var currencyCode = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Iso3LetterCode").AttemptedValue;
var money = (Money) bindingContext.Model;
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;
}
}
else
{
base.OnModelUpdated(controllerContext, bindingContext);
}
}
}
My ViewModel Lokks like this (some propertis omitted for clarity):
public class EditFeeEarningCapacityViewModel
{
public List<FeeEarner> FeeEarners { get; set; }
public class FeeEarner
{
public Money AverageChargeOutRate { get; set; }
}
}
My Edit Template for the Money type looks like this:
@model Core.Money
@{
int decimalPlaces;
if(!int.TryParse(string.Format("{0}", ViewData["DecimalPlaces"]), out decimalPlaces))
{
decimalPlaces = 0;
}
}
<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:n" + decimalPlaces + "}", Model.Amount)
})
</div>
@Html.HiddenFor(x => x.Iso3LetterCode)
For a form that has post values like this:
FeeEarners.index 3fa91d09-0617-4bea-ae3f-d84862be8c04
FeeEarners[3fa91d09-0617-4bea-ae3f-d84862be8c04].feeEarner.AverageChargeOutRate.Amount 500
FeeEarners[3fa91d09-0617-4bea-ae3f-d84862be8c04].feeEarner.AverageChargeOutRate.Iso3LetterCode GBP
I can't see how to detect the index of the item or the property name that I'm binding to. So essentially, how do I find the index of the item I'm trying to bind to and the name of the property that I'm trying to bind the data from?
I am not fimilar with that Helper but for collection i am doing a bit different trick.
define key
var key = "EditModel[{0}].{1}";
var index = 0;
then build form
foreach(var fee in Model.FeeEarners){
@Html.TextBox(string.Format(key, index, "PropertyNameFromYourFeeClass"));
//It will build text box and set value
}
On Controller side create action with input parameter
public ActionResult Save(EditFeeEarningCapacityViewModel editModel){
...your code here
}
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