我正在开发MVC2中的向导类型解决方案,我想阻止用户直接进入第2步,但是,我仍然希望它显示在URL中。
另外,由于可以随时保存进度,我仍然希望能够以编程方式转到Step2。我怎么能这样做?
[HttpGet]
public ActionResult Step1() {
return View("Step1View");
}
[HttpPost]
public ActionResult Step1(Stuff s) {
return RedirectToAction("Step2", new { S = s });
}
[HttpGet] //<-- how do I stop users going directly here
public ActionResult Step2(Stuff s) {
return View();
}
[HttpPost]
public ActionResult Step2(Stuff2 s) {
return RedirectToAction("Step3");
}
答案 0 :(得分:2)
我自己没有尝试过,但如果我这样做,我会考虑一下ActionFilters。我将创建一些描述向导数据的上下文对象以及该向导的步骤(可能以某种方式包装一两个模型)。
这个向导上下文可以自我“验证”,因为我可以问下一个有效步骤是什么。
然后,通过它,我从动作过滤器加载它,然后如果当前动作对该步骤无效,我重定向。
当然,我可以在没有动作过滤器的情况下做到这一点,只需将其作为我正在查看的方法的前导。就个人而言,我先做这个,然后玩动作过滤器试着让它看起来有点整洁,如果我有时间的话。
答案 1 :(得分:1)
首先,这将在很大程度上取决于临时保存数据的存储系统。操作过滤器应检查此存储,并查看步骤1数据是否存在。如果不是,您可以随时向ModelState
添加错误,从而使其无效。因此,您的第2步代码如下所示:
[HttpGet]
[CheckExistingData]
public ActionResult Step2(Stuff s)
{
if (!this.ModelState.IsValid)
{
return RedirectToAction("Step1");
}
return View(s);
}
因此。您的过滤器应检查现有数据,并且:
Stuff
参数或您编写重定向到操作(在步骤1 POST中)以提供复杂对象的方式并不是一种好方法。您应该整合数据存储,因此无论您的用户来到第2步,过滤器始终都会起作用。在第1步POST中,您应该将数据保存到此特定存储,然后重定向到第2步。
您有两种进入第2步的方案:
这样,您的第2步对两种情况都会起作用。您可以在向导中创建任意数量的步骤,同样的过程仍然可以正常工作。
答案 2 :(得分:1)
我已经完成了一个高度可重复使用的向导,只需这样做:
return Navigate();
从操作中,向导知道该怎么做(如果实现向导模式,这是可能的)。 Navigate()是在基础WizardController类上定义的方法。
这个工作的原因是,实质上,步骤信息被序列化到每个请求的页面(AJAX与否),并在控制器在OnActionExecuting方法中读取响应时反序列化。
框架使用WizardStep属性来了解哪个操作对应于哪个向导步骤,并且控制器使用WizardOptions属性进行修饰,该属性指示向导将如何允许自己导航。 EG:
[WizardStepOptions(WizardNavigatorRules.LeapBackOnly, WizardButtonRules.Both, WizardCompleteRules.DisableNavigation)]
public class MembershipFormController : WizardController<ESregister.Models.TheSociety.RegistrationData>
{
[WizardStep(1, "Start")]
public override ActionResult Start()
{
return Navigate();
}
它是一个梦想。如果在使用向导的过程中,您需要修剪或添加步骤,您只需使用Range属性定义要显示的步骤,也可以在基类WizardController上定义:
[WizardStep(2, "Category")]
public ActionResult Category()
{
return Navigate();
}
[HttpPost]
public ActionResult Category(int ? Category)
{
if (Category == null)
{
ModelState.AddModelError("Category", "You must fill in a Category!");
return Navigate();
}
if (Category == 3)
{
Range = new List<int> { 1, 2, 7, 8 };
}
else
{
Range = DefaultRange();
}
return Navigate();
}
向导框架自动实现PRG。您只需要在上述情况下提供HttpPost,例如,根据用户输入修剪步骤范围。
它还提供如下导航控件:
<% StepManager stepManager = (StepManager)TempData["stepManager"];
Html.WizardNavigator(stepManager); %>
Html.WizardButtons(stepManager, WizardButtonLocation.Top); %>
WizardNavigator显示/提供指向不同步骤的链接(如果允许则链接),WizardButtons是Start,Next,Continue,Previous和Confirm按钮。
它正在制作中。
我已经包含了所有这些细节,以显示可能的内容以及建议的解决方案是否有效。