【问题标题】:how to make a wizard with ASP.Net MVC如何使用 ASP.Net MVC 制作向导
【发布时间】:2010-09-22 18:24:23
【问题描述】:

我们的网站有多个“向导”,其中各种数据在多个页面上收集,直到最后一步才能提交到数据库。

使用 ASP.Net MVC 制作这样的向导的最佳/正确方法是什么

编辑:我的老板现在说“没有 javascript”——关于如何绕过这个限制有什么想法吗?

【问题讨论】:

  • 为什么“没有javascript”?我会改用 Flash 或 Silverlight :)
  • 我希望你的老板不再是你的老板了……因为他说的话……;)
  • 问他为什么“没有 Javascript”。

标签: c# .net asp.net-mvc wizard


【解决方案1】:

我不相信有最好/正确的方法,但我会这样做......

每个向导都有自己的页面。每个步骤都有自己的 div。所有步骤都采用相同的形式。

上一个/下一个按钮本质上会在流程的每个步骤中隐藏/显示 div。最后一步的提交按钮提交整个表单。使用 jQuery 实现这一点非常简单,并且由于所有向导步骤都在一个 ViewPage 中,因此易于维护。

在控制器端,您将有两个控制器方法,HttpVerbs.Get 版本用于准备表单以供查看,HttpVerbs.Post 版本将采用 FormsResult 并对其进行解析以获取提交所需的信息用户对存储/其他进程的回答。


哇,你的老板很臭。

这个答案几乎适用于禁用 javascript 的 ******(是的,他们两个)。您可以调整它以通过 CSS 隐藏下一个上一个按钮,并在您的 javascript 代码中取消隐藏它们。这样,使用 javascript 的人会看到向导,而没有 javascript 的人会看到整个表单(没有下一个/上一个按钮)。

另一个选项是为向导中的每个步骤创建一个视图。您可以将表单的中间结果存储在 Session 中。这种方式会花费大量的时间和精力来实现,这意味着你可能会在演示时从你的老板那里挤出一些加班时间,在午餐时花费大约 20 分钟的时间,javascript 路由是多么容易实现。

【讨论】:

  • 只是为了添加更多内容,您可以将向导的每个步骤放在 Partial 视图中,并在每个 DIV 上执行 Render.Partial。
  • 使用单一视图和 javascript 来隐藏/显示您提到的问题 - 随着向导的增长,您的页面将变得绝对巨大。当然,有 2-3 个步骤的向导可能没问题,但除此之外,你只是在自找麻烦。
  • @charles 有多少比过早优化更糟糕?
  • @charles 你说超过 3 个步骤会导致页面变得“绝对巨大”。因此,您担心页面会变大,从而减慢请求。换句话说,在您真正知道需要之前,您正在尝试优化响应时间。就这么简单,真的。不是试图煽动,只是回应你的担忧。当然,它们是有效的,但前提是您的向导页面引起了问题。或者你只是想通过说超过 3 个步骤 = 麻烦来“煽动”?
  • 别忘了,当 .NET 认为内存不足时,保存在 Session 中的数据随时可能丢失。
【解决方案2】:

如果您不能使用 JavaScript,则将每个步骤都设置为视图,并在控制器中使用方法,并将您的数据保持在会话中,直到准备好提交到数据库。

您可以使用 ActionLink HtmlHelper 方法制作 Next 和 Prev 按钮。

【讨论】:

  • 我会这样做,但只使用 TempData。是的,它也存储在 Session 中,但无需管理它,因为它已为您删除。
  • 对于向导,​​您需要跨多个页面的信息,因此您不希望在提交之前将其删除。将其保持在会话中允许您前进、后退或重新启动并保留已输入的数据。
  • 如果用户突然决定导航到应用程序的不同区域会发生什么?每次用户决定去其他地方时,都应该清除会话信息。
【解决方案3】:

另一种方法是将您使用向导构建的不完整对象保存到数据库中,然后将主键传递给向导的下一步。我知道这意味着您需要将一些数据库字段设为可空,但它确实具有额外的优势,您可以将主键保存在 cookie 中并允许用户稍后返回向导。此选项不需要 javascript 或会话状态。

【讨论】:

  • 为了提高安全性,你应该散列主键,否则黑客可能会拿走别人的对象
  • 如果每个步骤在数据库中都有自己的表,则不需要空值。
  • 如果用户选择取消,或者向导以其他方式中止怎么办?然后你会在数据库中得到不完整的垃圾条目。
  • 取消可以让系统清除数据。但是如果用户在应用程序中点击了不同的链接,那也需要调用 clear 方法。因此,您希望让用户遵循严格的工作流程,否则您的应用程序开始崩溃。
【解决方案4】:

使不同的面板都成为客户端...都以相同的形式...当按下最终提交按钮时,您可以同时发布所有值。

【讨论】:

    【解决方案5】:

    如果您不能使用 Javascript 并且不想将服务器资源用于 Session 变量,您还可以对在不同步骤中输入的值进行序列化和反序列化,并使用隐藏的输入字段来回传递。有点像 ASP.NET Webforms 中的 ViewState。

    【讨论】:

    • 此解决方案的问题是您最终存储在隐藏输入字段中的数据量,这会增加 HTTP 请求及其相应响应的大小。这两者都会影响您的网站对用户和其他用户的性能(因为它会影响您的带宽)。后者可能可以忽略不计,具体取决于访问向导的频率,但它可能会导致问题。如果要对数据进行序列化,最好将其临时存储在数据库表或会话中。
    • @charles,如果您预计向导中有如此巨大的流量,那么会话对象将比您在前面步骤的序列化/反序列化中遇到性能问题(甚至带宽问题)快得多以上绝对是更具可扩展性和更安全的(性能方面)。请记住,我们谈论的是 asp.net mvc,所以我 99% 确定会话不是分布式的,或者至少在状态服务器上。当心错误位置的微优化..
    • @jhexp,我不知道你怎么能说使用隐藏的输入字段比使用临时数据库表更具可扩展性和更安全的性能。与每次将其从数据库中拉出相比,在每次请求中来回传递一个巨大的字符串绝对不会获得更好的性能。哦,至于会话,为什么您认为会话没有分发?这完全取决于实现者,MVC 对此没有限制。
    • @charles 你想告诉我们每个步骤的完整数据库查询比在表单中具有隐藏字段更快且更具可扩展性?而且我并不是说 MVC 限制了分布式会话的实现,但这是一种非常罕见的情况。无论如何,许多高负载应用在服务器上都是无状态的。
    • @jhexp 您显然不知道与简单的数据库调用相比,HTTP 请求有多慢。增加该请求和响应的大小肯定比单个数据库调用要慢。那是高速连接,甚至不要开始拨号(是的,人们仍然使用拨号)。
    【解决方案6】:

    如果有帮助,我会整理一个登录向导并将其背后的想法记录在我的博客上:link text

    【讨论】:

      【解决方案7】:

      您可以使用 NuGet 上提供的简单组件 MVCWizard.Wizard。 WizardController 允许您使用局部视图创建向导。还有一个 AutoWizardController 可以在单个视图中呈现整个向导。所有这些组件都与会话一起操作以存储模型状态。

      【讨论】:

      • 有代码示例吗?你的控制器都在一个类中,看不到代码。
      • @rob NuGet 上有示例项目,如果你愿意,我可以给你示例的源代码。
      • 那太好了,你可以通过我的网站联系我。
      【解决方案8】:

      本题有一个非常简单灵活可扩展的方法:How to simplify my statefull interlaced modal dialogs in ASP.NET MVC

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-29
        • 2013-06-22
        • 1970-01-01
        • 2016-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        相关资源
        最近更新 更多