なんらかのウィザードを作成する必要がある場合は、ステップ間で状態を維持する方法が必要です。
ウィザードの各ステップで PRG (Post/Redirect/Get) パターンに従う必要があるため、ViewBag はこれには適していません。
TempData は、ステップ間を前方に移動するために機能しますが、ユーザーが戻ったり、ステップに直接移動したりすると失敗します。
したがって、寿命の長いものが必要です。ASP.NET セッション オブジェクトまたはデータベースは、どちらもこれに適した候補です。
次に例を示します。
public class WizardController : Controller
{
public ActionResult Step1()
{
var session = GetWizardSession();
if (session.Step1 == null)
{
session.Step1 = new Step1View
{
PricingSecurityIds = new SelectList(new[] { 1, 2, 3, 4, 5 }),
SomeOtherIds = new SelectList(new[] { 1, 2, 3, 4, 5 })
};
}
return View(session.Step1);
}
[HttpPost]
public ActionResult Step1(Step1View cmd)
{
var session = GetWizardSession();
// save the wizard state
session.Step1.SelectedPricingSecurityId = cmd.SelectedPricingSecurityId;
session.Step1.SelectedSomeOtherId = cmd.SelectedSomeOtherId;
// now onto step 2
session.Step2 = new Step2View
{
PricingSecurityId = cmd.SelectedPricingSecurityId,
SomeOtherId = cmd.SelectedSomeOtherId,
Name = "John Smith"
};
return RedirectToAction("step2");
}
public ActionResult Step2()
{
return View(GetWizardSession().Step2);
}
public WizardSession GetWizardSession()
{
var session = Session["wizardsession"];
if (session == null)
{
session = new WizardSession();
Session["wizardsession"] = session;
}
return session as WizardSession;
}
}
public class Step1View
{
public SelectList PricingSecurityIds { get; set; }
public SelectList SomeOtherIds { get; set; }
public int SelectedPricingSecurityId { get; set; }
public int SelectedSomeOtherId { get; set; }
}
public class Step2View
{
public int PricingSecurityId { get; set; }
public int SomeOtherId { get; set; }
public string Name { get; set; }
}
public class WizardSession
{
public Step1View Step1 { get; set; }
public Step2View Step2 { get; set; }
}
- Step1では、 を呼び出します
GetWizardSession
。Session
これにより、ウィザードの各ステップで収集したすべての情報を含むオブジェクトが ASP.NET から返されます。この例では、各ステップ (つまりsession.Step1
) の ViewModel を格納するだけです。
- Step1 がセッションに存在するかどうかを確認し、存在しない場合は作成します。次に、Step1 モデルをビューに渡します。
- ユーザーがフォームを送信すると、 の「選択済み」の値が更新され
session.Step1
ます。これにより、ユーザーが /step1 に戻った場合に、その値を「記憶」することが保証されます。次に、 Step2のモデルを構築し、セッションに保存します。
- /step2 に移動すると、モデルがセッションに存在すると想定されます (モデルは step1 からここに移動する必要があるため)。
return View(GetWizardSession().Step2);
ビュー:
ステップ1
@model MvcWizardDemo.Controllers.Step1View
@{
ViewBag.Title = "Step1";
}
<h2>Step1</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Step1View</legend>
<div class="editor-label">
@Html.LabelFor(m => m.PricingSecurityIds)
</div>
<div class="editor-field">
@Html.DropDownListFor(m => m.SelectedPricingSecurityId, Model.PricingSecurityIds)
@Html.ValidationMessageFor(m => m.PricingSecurityIds)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.SomeOtherIds)
</div>
<div class="editor-field">
@Html.DropDownListFor(m => m.SelectedSomeOtherId, Model.SomeOtherIds)
@Html.ValidationMessageFor(m => m.SomeOtherIds)
</div>
<p>
<input type="submit" value="Next" />
</p>
</fieldset>
}
ステップ2
@model MvcWizardDemo.Controllers.Step2View
@{
ViewBag.Title = "Step2";
}
<h2>Step2</h2>
Hi, @Model.Name you selected the following values in the previous step:
<p>
<strong>Security Id:</strong> @Model.PricingSecurityId
</p>
<p>
<strong>Some other Id:</strong> @Model.SomeOtherId
</p>