18

アイテムのリストをバインドするために、 Steve SandersonsBeginCollectionItem拡張機能を使用しています。これは、プリミティブ型ではうまく機能します。私が抱えている問題は、私が書いたカスタム モデル バインダーの場合、バインドしているアイテムの完全な名前とインデックスを生成する方法がわからないことです。

現在、私のモデル バインダーは次のようになっています。

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);
        }
    }
}

私のViewModel Lokksは次のようになります(わかりやすくするために一部のプロパティは省略されています):

public class EditFeeEarningCapacityViewModel
{

    public List<FeeEarner> FeeEarners { get; set; }

    public class FeeEarner
    {
        public Money AverageChargeOutRate { get; set; }
    }
}

Money タイプの編集テンプレートは次のようになります。

@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)

次のような投稿値を持つフォームの場合:

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

アイテムのインデックスまたはバインドしているプロパティ名を検出する方法がわかりません。基本的に、バインドしようとしているアイテムのインデックスと、データをバインドしようとしているプロパティの名前を見つけるにはどうすればよいでしょうか?

4

1 に答える 1

1

私はそのヘルパーに慣れていませんが、コレクションについては少し異なるトリックを行っています。

キーを定義する

var key = "EditModel[{0}].{1}";

変数インデックス = 0;

次にフォームを作成します

foreach(var fee in Model.FeeEarners){
   @Html.TextBox(string.Format(key, index, "PropertyNameFromYourFeeClass"));
//It will build text box and set value
}

コントローラー側では、入力パラメーターを使用してアクションを作成します

public ActionResult Save(EditFeeEarningCapacityViewModel editModel){
...your code here
}
于 2012-12-19T08:13:05.967 に答える