5

假设我有一个 Web 应用程序,其实现类似于一组向导页面来编辑一个复杂的对象。在用户单击“完成”按钮之前,对象不会保存到后端系统(要求),因此同时我必须将有关对象的全部信息保持在某种会话状态.

此外,某些向导页面必须显示包含大量项目的组合框和列表框。这些项目是使用 Web 服务从后端系统获取的。

巧合的是,向导允许用户自由地从一个向导页面跳转到任何其他页面(使用表单顶部的选项卡链接),因此这不是简单的“下一个,下一个...完成”的事情。

附加限制:Web 应用程序在 Web 场上运行,客户厌倦了使用服务器端会话状态。在最好的情况下,他们希望将会话状态的大小保持在最小(他们过去曾遇到过这个问题)。

所以这里基本上有两个问题:

  1. 如何/在哪里保存用户在向导中输入的数据?
  2. 是否缓存从后端接收的组合/列表项,如果是,在哪里?

我正在考虑的选项:

  1. 将对象存储在类似 WebForms 的ViewState 中(通过将其序列化到 HTML 页面中)。这也将包括组合框项目。显然,HTML 页面变得非常大可能会出现问题,因此 Web 应用程序会很慢。

  2. 将其存储到服务器端会话状态中,无论客户的意愿如何,也不知道性能将如何受到影响,直到在实际的 Web 场(项目后期)上进行测试。

我无法在两者之间做出决定。或者还有其他选择吗?

4

8 回答 8

5

为什么要缓存?您可以只拥有每个页面都是 div 或面板的选项卡式页面,并且只显示与您的选项卡相关的当前 div。这样您就不必在用户提交表单时跟踪和处理所有输入。

于 2009-08-06T09:12:07.363 回答
3

是否可以将向导数据存储在数据库的临时表中?当用户完成向导时,数据将从临时表中复制并删除。临时表包含一个时间戳以删除任何旧的未完成数据。

于 2009-08-06T09:26:20.813 回答
2

正如 Daisy 所说,它不必被缓存。您还可以使用隐藏的表单域。因为这些可以映射到每个控制器操作上的相同对象,所以您可以通过连续页面逐步构建对象。

//Here's a class we're going to use
public class Person
{
  public int Age {get;set;}
  public string Name {get;set;}

  public Person()
  {
  }
}

//Here's the controller
public Controller PersonCreator
{
  public ActionResult CreatePerson()
  {
    //Posting from this page will go to SetPersonAge, as the name will be set in here.
    return View();
  }

  public ActionResult SetPersonAge(Person person)
  {
    //This should now have the name and age of the person
    return View(person);
  }
}

//Here is your SetPersonAge, which contains the name in the model already:
<%= Html.Hidden("Name", Model.Name) %>
<%Html.TextBox("Age") %>

差不多就是这样。

于 2009-08-06T09:20:25.147 回答
1

如果您不能使用 ajax(用于验证和下拉菜单以及将向导转换为选项卡式页面的能力)并且不能使用 html5(用于下拉缓存和在本地存储中保存表单状态),那么我认为您完全没有可用的“最佳实践”和你必须求助于坏(或更糟)的一个。

由于 MVC 在会话使用方面是 WebForms 的反对者,也许您可​​以使用一种解决方法?例如,除了将所有这些值存储在您需要稍后清理的一些临时数据库记录中之外,您还可以为 Windows Server 设置AppFabric 扩展并使用它来存储下拉列表项(范围可以是所有用户,所以如果更多用户同时使用系统,您只需要一次调用 Web 服务即可刷新缓存),并且还可以在步骤之间临时存储您的对象。您可以将 AppFabric 中的临时对象设置为自动过期,因此无需进行清理。如果您通过 Web 服务广泛调用另一个系统,它也有助于加速系统的其他部分。

于 2011-09-24T23:23:42.287 回答
1

我可以建议更多的选择

  1. 将整个向导作为一个页面,在客户端通过 javascript 显示和隐藏内容的选项卡。这可能会导致初始页面加载速度较慢。

  2. 使用缓存应用程序块(或类似的东西)在服务器缓存数据。这将允许所有用户共享此数据的单个实例,而不是在所有会话中复制。现在数据更轻了,您可以说服客户允许在会话中存储。

于 2009-08-06T09:31:51.020 回答
1

MVC 社区中有很多反对使用 Sessions 的阻力。问题是我们很多开发人员都在构建像银行网站这样的登录系统。人们可能会争论隐藏字段,这适用于某些情况,但是当我们需要让用户超时以确保安全性和合规性时,您有多种选择。Cookie 不可靠。依赖 Javascript 计时器是不可靠的,也不符合 508 标准,因为目标应该是优雅地降级。因此对于登录,会话是一个不错的选择。如果您将时间写入客户端浏览器、服务器数据库或服务器文件系统,您仍然需要管理每个用户的时间。

因此,谨慎使用 Sessions,但不要害怕它们。对于向导,​​从技术上讲,您可以序列化传递它们的隐藏字段。我怀疑需求和范围会变得更大,使用 Sessions 的授权/身份验证实现将成为应用程序的关键。

于 2011-09-01T02:44:05.803 回答
0

我一直在处理同样的问题,虽然我的要求有点简单(只保留几个字符串的状态),但我的解决方案可能对你有用。我也有兴趣听听其他人对这种方法的看法。

我最终做的是:在控制器中,我只是将我想要的数据转储到控制器的 Session 属性中,然后在下次需要时将其拉出。像你这样的情况:

//Here's the controller
public Controller PersonCreator  
{  
    public ActionResult CreatePerson()  
    {    
        //get the age out of the session
        int age = (int)(Session["age"]);
        //do something with it...
        return View();  
    }  
    public ActionResult SetPersonAge(Person person)  
    {  
        //put the age in the session
        Session.Add("age", person.Age);
        return View(person);  
    }
}

我喜欢这个的一点是我不必在我的视图页面上放置一堆隐藏的参数。

于 2009-08-07T22:36:50.250 回答
0

这个问题的答案可以在Steve Sanderson 的 ASP.NET MVC 2/3中找到,并且需要参考 MVC Futures 程序集。这个指向Google 图书的链接正是他所做的。

实质上,您将向导数据序列化到视图。呈现一个隐藏字段,存储所有获取的信息。

OnActionExecuting您的控制器可以通过使用and OnResultExecuted(以迎合重定向)将其传递给下一个视图来计算出要做什么。

读一读——他比我解释得更透彻。

于 2013-06-19T16:04:04.510 回答