0

ビューモデルのプロパティの一部である複雑なクラスがあります。ビューモデルにはワイン クラス プロパティがあり、ワイン クラスには CaseProductions という ICollection プロパティがあります。CaseProduction クラスにもいくつかのプロパティがあります。

create GET イベントで、NewWineViewModel がインスタンス化され、GetCaseProductionDefaults が実行され、いくつかのデフォルト値を持つがほとんど空である CaseProduction クラスのリストが作成されます。

今、私はもともと剃刀を使って foreach ステートメントを実行し、自分のテーブルを好きなようにポップアウトしました。しかし、私は、このタイプの IEnumerable を POST のビューモデルにバインドするのにうまくいかないことを見てきました。以下を使用しようとしましたが、サイコロはありません。

EditorFor(m => m.Wine.CaseProductions)

これを処理する最善の方法は何かについてのアドバイスを本当に探しています。各ワインにはケースプロダクションのコレクションがあり、それをビューモデル内のワインにバインドします。これらの要素のIDをかみそりで編集して、それらが確実にバインドされるようにする方法はありますか? これを処理する最良の方法は何ですか?

ビューモデル:

    public class NewWineViewModel
    {

        public Wine Wine { get; set; }
        public VOAVIRequest VOAVIRequest { get; set; }
        public bool IsRequest { get; set; }

        public Dictionary<int, int> BottlesPerCase { get; set; }
        public SelectList VarTypes { get; set; }
        public SelectList Origins { get; set; }
        public SelectList Apps { get; set; }
        public SelectList Vintages { get; set; }
        public SelectList Importers { get; set; }
}

ケース生産クラス:

public class CaseProduction
{
    public int CaseProductionID { get; set; }
    public int WineID { get; set; }
    public int CaseProductionSizeID { get; set; }
    public int CaseCount { get; set; }
    public int CountPerCase { get; set; }

    public virtual CaseProductionSize CaseProductionSize { get; set; }
    public virtual Wine Wine { get; set; }

}

デフォルトのケースプロダクションの取得:

public List<CaseProduction> GetCaseProductionDefaults(vfContext db)
{
    //creates blank list of all formats
    List<CaseProduction> cp = new List<CaseProduction>();
    foreach (CaseProductionSize size in db.CaseProductionSizes)
    {
        int defaultBottlesPerCase = 1;
        switch ((CaseProductionSizeEnum)size.CaseProductionSizeID)
        {
            case CaseProductionSizeEnum.s187ml:
                defaultBottlesPerCase= 24;
                break;
            case CaseProductionSizeEnum.s375ml:
                defaultBottlesPerCase = 12;
                break;
            case CaseProductionSizeEnum.s500ml:
                defaultBottlesPerCase = 12;
                break;
            case CaseProductionSizeEnum.s750ml:
                defaultBottlesPerCase = 12;
                break;
            default:
                defaultBottlesPerCase = 1;
                break;
        }

        cp.Add(new CaseProduction { CaseProductionSizeID = size.CaseProductionSizeID, CountPerCase = defaultBottlesPerCase, CaseProductionSize = size, WineID = this.Wine.WineID });
    }
    return cp;
}

ケース生産テーブルのカミソリ コード:

  @foreach (vf2.Models.CaseProduction cp in Model.Wine.CaseProductions)
            {
                <tr>
                    <td>@cp.CaseProductionSize.Name
                    </td>
                    <td>@Html.Raw(@Html.TextBoxFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CaseCount, new { @class = "caseCount", id = "txt" + cp.CaseProductionSize.Name }).ToString().Replace("CaseCount","txt" + cp.CaseProductionSize.Name))
                    </td>
                    <td>
                        @Html.DropDownListFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CountPerCase, new SelectList(Model.BottlesPerCase, "Key", "Value", cp.CountPerCase), new { @class = "countPerCase", id = "ddl" + cp.CaseProductionSize.Name, name = "ddl" + cp.CaseProductionSize.Name})
                    </td>
                    <td class="totalBottleCalc">
                    </td>
                </tr>
 }

ケースプロダクション コレクションのインスタンス化:

 public ActionResult Create(int ID = 0, int VintUpID = 0)
        {
            NewWineViewModel nw = new NewWineViewModel();

            nw.Wine.CaseProductions = nw.GetCaseProductionDefaults(db);
            nw.BottlesPerCase = nw.GetBottlesPerCase(db);
4

2 に答える 2

0

CaseProductionオブジェクトのように見えないため、モデル バインダーがオブジェクトを認識していないと思いCaseProductionます。

の名前を変更CaseCountしましたが、CaseProductionSizeID はありません (またCaseProduction、いくつかのプロパティがありません。ループでは、すべてのプロパティを含め、名前を POCO の名前と一致させる必要があります。そうしないと、モデル バインダーは何を認識しません。必要に応じて、すべてのプロパティを隠しフィールドに入れることができます。

于 2012-09-28T19:04:44.750 に答える
0

親モデルのコンストラクターで、ネストされたリストと複雑なモデルをインスタンス化する必要があります。デフォルトのモデル バインダーは、子クラスをインスタンス化しません。

そうすれば、EditorFor(m => m.Wine.CaseProductions) を使用でき、使用している複雑なビュー コードは必要ありません。

CaseProduction のレンダリング方法をカスタマイズする場合は、~/Shared/EditorTemplates に CaseProduction.cshtml ファイルを作成すると、この定義を使用してコレクション内の各アイテムがレンダリングされます (コレクションが自動的に反復処理されます)。 .

また、ビューで linq クエリを実行しないでください。あなたの問題は、データ エンティティをビューに直接渡しているように見えることです。これはデザインが悪い。代わりに、ビューをレンダリングするために必要な情報のみを含む ViewModel を作成する必要があります。次に、View モデルに割り当てる前にデータをフィルター処理します。

于 2012-09-28T18:52:08.467 に答える