マルチページ ウィザード UI の一部として NuGet の MVCWizard.Wizard を使用しようとしています。
サブセクションとして「子」クラスを持つ「親」モデルクラスがいくつかあります。
public class MainModel
{
public virtual int MainModelId { get; set; }
public virtual PersonalDetails CustomerPersonalDetails { get; set; }
public virtual AddressDetails CustomerAddressDetails{ get; set; }
public virtual FinanceDetails CustomerFinanceDetails{ get; set; }
}
試行錯誤の結果、MVCWizard.Wizard を使用するには、表示したいページのサブセクションごとに「WizardManager」を作成する必要があることがわかりました (つまり、1 つの WizardManager、コントローラー、部分ビューなどを CustomerPersonalDetails 用に、1 つをCustomerAddressDetails など..)
..ここまでは順調ですね..
各サブセクションのコントローラーの作成は、WizardController T を継承します。ここで、T はモデルです。私がやりたいのは、各サブセクションが MainModel を完全に受け入れるために使用するコントローラーをコーディングし、そこから必要に応じて MainModel.Child を各パーシャルビューに渡すことです (MVCWizard.Wizard が必要とする方法)。
このようにすると、すべて正常にコンパイルされますが、使用中にウィザード ページ (部分ビュー) の間を行き来すると、base.Wizard().WizardModel のデータが消去されます。
前後に移動するときに Base.Wizard().WizardModel にデータを保持するには、WizardManager ごとに子クラスの型を明示的に指定する必要があることがわかりました。
だから.. (コントローラー)
public MyController : WizardManager < MainModel >...
public PartialViewResult SubsectionPage1(MainModel mdl)..
(意見)
@model MainModel
CustName: @Html.TextBoxFor(m => m.CustomerPersonalDetails.CustName)
..動作しているように見えますが、データは保持されていません..しかし..
(コントローラー)
public MyController : WizardManager< PersonalDetails >...
public PartialViewResult SubsectionPage1(PersonalDetails details)..
(意見)
@model PersonalDetails
CustName: @Html.TextBoxFor(m => m.CustName)
うまく動作します... MVCWizard.Wizard が 1 つ以上の「子」型を保持する「複雑な」モデルを処理できないように見えるのはなぜですか? 最終的にはコーディングして、これらの小さなモデルを WizardManager に渡し、それらを結合してドメイン モデルにマッピングしてからデータストアに永続化することができますが、説明をいただければ幸いです..
* 編集 *
わかりました、もう少し掘り下げてみましたが、最初のモデル バインディングはほとんどの通常の状況で問題なく動作するはずです。しかし、MVCWizard.Wizard を使用する場合、MVCWizard.Wizard の「EnableSimpleMerge」機能に問題があるようです。ページのナビゲーション中に使用され、マージ関数がリフレクションを使用してモデル内のプロパティを検出する方法に問題があるようです。私の最初の外観から、より複雑なモデル構造内の子オブジェクトを再帰して「発見」するようにコード化されているようには見えません..
private void Merge(T wizard, T model)
{
foreach (PropertyInfo info in model.GetType().GetProperties())
{
object obj2 = info.GetGetMethod().Invoke(model, null);
if (obj2 != null)
{
wizard.GetType().GetProperty(info.Name).GetSetMethod().Invoke(wizard, new object[] { obj2 });
}
}
foreach (FieldInfo info3 in model.GetType().GetFields())
{
object obj3 = info3.GetValue(model);
if (obj3 != null)
{
wizard.GetType().GetField(info3.Name).SetValue(wizard, obj3);
}
}
}