0

私は当社で最初の MVC3 プロジェクトに取り組んでおり、ブロックにぶつかりました。何が起こっているのか誰も理解できないようです。

ページで使用している複雑なモデルがあります。

public class SpaceModels : List<SpaceModel> {
    public bool HideValidation { get; set; }
    [Required(ErrorMessage=Utilities.EffectiveDate + Utilities.NotBlank)]
    public DateTime EffectiveDate { get; set; }

    public bool DisplayEffectiveDate { get; set; }
}

コントローラーで、Spaces が結合されるとき (これが目的の Space になります) に備えて、空白の SpaceModels を持つ SpaceModels オブジェクトを作成します。

// Need a list of the models for the View.
SpaceModels models = new SpaceModels();
models.EffectiveDate = DateTime.Now.Date;
models.DisplayEffectiveDate = true;
models.Add(new SpaceModel { StoreID = storeID, SiteID = siteID, IsActive = true });

        return View("CombineSpaces", models);

次に、ビューで、その SpaceModels オブジェクトをモデルとして使用し、発効日の TextBox を作成するフォームで使用しています。

@model Data.SpaceModels

@using (Html.BeginForm("CombineSpaces", "Space")) {
    <div class="EditLine">
        <span class="EditLabel LongText">
            New Space Open Date
        </span>
        @Html.TextBoxFor(m => m.EffectiveDate, new {
                        size = "20",
                        @class = "datecontrol",
                        // Make this as a nullable DateTime for Display purposes so we don't start the Calendar at 1/1/0000.
                        @Value = Utilities.ToStringOrDefault(Model.EffectiveDate == DateTime.MinValue ? null : (DateTime?)Model.EffectiveDate, "MM/dd/yyyy", string.Empty)
        })
        @Html.ValidationMessageFor(m => m.EffectiveDate)
    </div>

    <hr />        

    Html.RenderPartial("_SpaceEntry", Model);
}

レンダリングされる部分ビューは、すべての SpaceModel を繰り返し処理し、個々の SpaceModel オブジェクトの編集フィールドを含む を作成します。(私はリストを使用して、スペースが細分化されたときに同じビューを使用しています。)

次に、HttpPost では、EffectiveDate はまだ DateTime.MinValue のデフォルトに戻っています。

[HttpPost]
public ActionResult CombineSpaces(SpaceModels model, long siteID, long storeID, DateTime? effectiveDate) {
// processing code
}

そのDateTimeを追加しましたか?effectiveDate パラメーターを使用して、変更された値が実際に戻ってくることを証明します。TextBox のレンダリングを _SpaceEntry 部分ビューに移動しようとしましたが、そこでも何も機能しませんでした。

@Html.EditorFor(m => m.EffectiveDate)の代わりにを使用してみまし@Html.TextBoxFor()たが、それでも DateTime.MinValue が返されました。(ちなみに、上司は を使用してレンダリングの制御を放棄することを好みません@Html.EditorForModel。)

私が見逃している単純なものがなければなりません。他に何か必要な場合はお知らせください。

4

2 に答える 2

1

特にのソース コードを見ると、コレクション タイプが検出された場合、個々の要素がバインドされますが、リスト オブジェクト自体のプロパティはバインドされません。DefaultModelBinderBindComplexModel()

于 2012-08-28T23:20:53.900 に答える
1

モデル バインディングが行うことは、ビュー内のものまたは要素の名前を、モデル内のプロパティまたはアクション メソッド内のパラメーターと一致させようとすることです。これらのパラメーターをすべて渡す必要はありません。必要なのは、それらをビュー モデルに追加してから、TryUpdateModelアクション メソッドを呼び出すことだけです。SpaceModel または List で何をしようとしているのかわかりませんが、List から継承する必要はありません。あなたがそれをする正当な理由があると確信しています。これが私がそれを行う方法です。

ビューモデル

public class SpacesViewModel
{
    public DateTime? EffectiveDate { get; set; }
    public bool DisplayEffectiveDate { get; set; }
    public List<SpaceModel> SpaceModels { get; set; }
}

GET アクション メソッド

[ActionName("_SpaceEntry")]
public PartialViewResult SpaceEntry()
{
    var spaceModels = new List<SpaceModel>();
    spaceModels.Add(
        new SpaceModel { StoreID = storeID, SiteID = siteID, IsActive = true });

    var spacesVm = new SpacesViewModel
    {
        EffectiveDate = DateTime.Now,
        DisplayEffectiveDate = true,
        SpaceModels = spaceModels
    };

    return PartialView("_SpaceEntry", spacesVm);
}

POST アクション メソッド

[HttpPost]
public ActionResult CombineSpaces() 
{
    var spacesVm = new SpacesViewModel();

    // this forces model binding and calls ModelState.IsValid 
    // and returns true if the model is Valid
    if (TryUpdateModel(spacesVm))
    {
        // process your data here
    }
    return RedirectToAction("Index", "Home");
}

そして景色

<label>Effective date: </label>
@Html.TextBox("EffectiveDate", Model.EffectiveDate.HasValue ?
    Model.EffectiveDate.Value.ToString("MM/dd/yyyy") : string.empty, 
    new { @class = "datecontrol" })

次のような非表示フィールドを使用して、フォーム データを明示的にバインドする必要がある場合があります。

@Html.HiddenField("EffectiveDate", Model.EfectiveDate.)

SpaceModel オブジェクトのプロパティをバインドするには、SiteID などの個々のプロパティをビュー モデルに追加するか、単一の SpaceModel の SpaceModel プロパティを追加します。複雑なモデルを正常にバインドする場合Dictionaryは、リストではなく、キーと値のペアが設定されたモデルとして追加します。次に、ディクショナリをビュー モデルに追加する必要があります。階層データの辞書の辞書を追加することもできます。

これが役立つことを願っています:)

于 2012-08-29T16:53:25.250 に答える