12

私たちは、Editor-Templateを動的プロパティで動作させることを試みてきました-無駄に。多分あなたの一人が私たちを助けることができます。

これが大まかに私たちのクラスです:

public class Criterion
{
    ...
    public string Text { get; set; }
    public dynamic Value { get; set; }
    public Type Type { get; set; }
    ...
}

私たちのかみそりのビューは、それぞれがその中に基準のリストを含むセクションのリストを含むモデルを取得します。(これらの情報は実行時に取得されます。)これらの基準はすべて編集モードで表示する必要があります-実際のタイプに関して:(抜粋)

@for (int i = 0; i < model.Sections.Count(); i++)
{
    for (int j = 0; j < model.Sections[i].Criteria.Count(); j++)
    {
        var criterion = model.Sections[i].Criteria[j];
        var type = criterion.Type.Name;
        var name = "Sections[" + i + "].Criteria[" + j + "].Value";
        var criterionDisplayName = criterion.Text;
        <label for="Sections_@(i)__Criteria_@(j)__Value">@criterionDisplayName</label>
        @Html.Editor(name, type)
    }
}

これは、たとえばチェックボックスを正しく表示しますが、チェックボックスのステータスを正しく設定するために値を使用しません(criteria.Valueがtrueかどうかをチェックします)。同じことが、のような他のタイプにも当てはまりintsます。(POSTリクエストの後でフォームに正しく入力されますが、これはMVCが一時モデルを使用してユーザー入力を再作成するためです。)

私たちが試し、調査した限り、次のタイプのプロパティでEditorテンプレートを使用することも可能dynamicですか?はいの場合-どうすればそれを機能させることができますか?(可能なタイプで識別したくありません。実際のタイプに基づいて適切なエディターテンプレートを使用するMVCフレームワークが必要です。)

4

1 に答える 1

17

ダイナミクスは、ASP.NET MVC にうまく適合しません。彼らは私に思い出させ、私は私の体の非常に深い構造からViewBag嫌います. ViewBagだから私は別のアプローチを取ります。

たとえば、次のモデルを見てみましょう。

public class Criterion
{
    public string Text { get; set; }
    public object Value { get; set; }
}

値は、処理したい任意の型にすることができます。

これで、このモデルにデータを入力するコントローラーを作成できます。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new[]
        {
            new Criterion { Text = "some integer", Value = 2 },
            new Criterion { Text = "some boolean", Value = true },
            new Criterion { Text = "some string", Value = "foo" },
        };
        return View(model);
    }
}

対応するビュー:

@model IList<Criterion>

@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Count; i++)
    {
        <div>
            @Html.LabelFor(x => x[i], Model[i].Text)
            @Html.EditorFor(x => x[i].Value, "Criterion_" + Model[i].Value.GetType().Name)
        </div>
    }

    <button type="submit">OK</button>
}

処理したいタイプごとに、対応するエディター テンプレートを定義できます。

~/Views/Shared/EditorTemplates/Criterion_String.cshtml:

@model string
@Html.TextBoxFor(x => x)

~/Views/Shared/EditorTemplates/Criterion_Boolean.cshtml:

@model bool
@Html.CheckBoxFor(x => x)

~/Views/Shared/EditorTemplates/Criterion_Int32.cshtml:

@model int
@{
    var items = Enumerable
        .Range(1, 5)
        .Select(x => new SelectListItem 
        { 
            Value = x.ToString(), 
            Text = "item " + x 
        });
}

@Html.DropDownListFor(x => x, new SelectList(items, "Value", "Text", Model))

このモデルをビューに表示することは、明らかに最初のステップにすぎません。ユーザーが何らかの処理のために POST コントローラー アクションで入力した値を取得する必要があると思います。この場合、いくつかの小さな調整が必要です。実行時に正しい型をインスタンス化し、各行の非表示フィールドとして具象型を含めることができるカスタム モデル バインダーを追加する必要があります。で既に例を示しましたthis post。また、この例では、型を直接操作する代わりに基本クラスを使用していることにも注意してobjectください。

于 2012-07-15T08:16:00.887 に答える