【问题标题】:How can I persist objects between requests with ASP.NET MVC?如何使用 ASP.NET MVC 在请求之间保留对象?
【发布时间】:2011-08-07 02:40:15
【问题描述】:

我刚刚开始学习 ASP.NET MVC,我想知道如何在对控制器操作方法的后续请求之间保留模型对象?

例如说我正在创建一个联系人列表网络应用程序。用户可以在其列表中创建、更新、重命名和删除联系人。但是,我也希望用户能够上传从其他程序导出的联系人列表。然而,我不想只是在上传的文件中自动添加所有联系人,我想给用户一个辅助表单,他们可以在其中选择哪些上传的联系人应该实际添加到他们的列表中。

首先我有一个ContactController.Upload() 方法,它显示了一个上传表单。这将提交给ContactController.Upload(HttpPostedFileBase file),后者读取发布到一组联系人模型对象中的文件。然后我想显示列表中所有联系人姓名的列表,并允许用户选择那些应该添加到他们的联系人列表中的人。这可能是一个需要拆分为多个页面的长列表,并且我可能还希望允许用户在将联系人实际添加到他们的联系人列表之前编辑他们的详细信息。

在用户上传文件和最终提交所需的特定联系人之间,我应该将模型对象保存在哪里?我宁愿不立即将所有上传的联系人加载到后端数据库中,因为用户最终可能只选择少数几个来实际添加。然后其余的将需要删除。此外,我还必须考虑用户上传文件但从未真正完成上传的情况。

据我了解,控制器的实例只持续一个请求。那么我应该在我的联系人控制器上创建一个包含所有最新上传的联系人模型对象集合的静态属性吗?然后有一些进程定期检查这些集合的年龄并清除任何超过某个指定到期时间的集合?

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    控制器上的静态属性很麻烦。首先,它不能在网络场中工作,其次,您必须处理来自不同用户的多个请求。如果你真的不想使用你的数据库,你可以使用 ASP.NET Session。

    【讨论】:

    • 是的,静态属性似乎是个坏主意。我应该使用 Session 还是 TempData?我正在阅读两者,但不确定它们的区别。
    【解决方案2】:

    您也可以使用HttpContext.Cache,它支持开箱即用的过期(和滑动过期)。

    或者,也许更好(但工作量更大),您可以使用 cookie 并让用户在最终发布给您之前使用浏览器中的 javascript 修改数据。

    但是,我强烈建议将上传的信息存储在数据库中。

    正如您所指出的,它可能包含大量数据,用户可能希望在单击“确认”之前对其进行编辑。如果用户的机器(或浏览器)崩溃或者她不得不紧急离开会发生什么?

    根据您存储数据的方式,这种情况下的数据可能会丢失。即使您使用用户 id 作为缓存键,服务器重启、缓存过期或缓存溢出也会导致数据丢失。

    最好的解决方案可能是数据库和 cookie 存储的组合,其中数据库将信息保存在临时集合中。每 n 分钟,或在分页时,将修改后的数据发送到服务器并在数据库中更新。

    【讨论】:

    • 我并不担心丢失数据。如果用户上传文件并且他们的浏览器崩溃了,如果他们必须再次上传文件,这并不是世界末日。使用 TempData 或 Session 怎么样?虽然如果我在 proc 中使用 Session-State 模式,但我的 UploadData 模型对象需要可序列化正确吗?如果有什么不同的话,这些上传的文件大约是 200kb 到 1mb。当然,我可能只是想多了,因为这是我的第一个 ASP.NET 站点。
    • TempData 基本上是会话的包装器,它会自动删除下一个请求 AFAIK 中的信息。关键不是再次上传文件:丢失的是 edits - 这可能非常烦人。对象不需要可序列化 - 毕竟,它们没有被序列化。 1MB 不算小。我真的不明白你为什么不把这个写到数据库中。
    • 好吧,我最终得到了一个稍微不同的解决方案。当用户上传文件时,服务器只是保存文件,并触发线程池上的一个工作项来实际读取文件并将数据加载到数据库中。这样,当服务器读取他们的文件时,这个用户就不会等待他们的浏览器响应。
    【解决方案3】:

    不,您不想要静态属性,因为这对于控制器的所有实例都是静态的,即使对于其他用户也是如此。

    相反,您应该创建一个用于将数据上传到的表。该表将用作用户上传数据和完成流程之间的中介。完成后,将要保留的联系人复制到永久表中,然后删除临时数据。然后,您可以每隔一段时间运行一个进程,清除超过指定时间限制的不完整数据。

    【讨论】:

      【解决方案4】:

      将数据存储在会话或内存中的问题是,如果用户上传了 50k 或更多联系人,会发生什么情况。然后,您在内存中有一个非常大的数据集需要处理,这取决于您的平台可能会影响应用程序的性能。

      如果这永远不会成为问题并且导入的联系人列表的大小是可管理的,您可以使用会话或缓存来存储数据集以进行进一步修改。只需记住在用户提交更改时清除它,您不希望会话中有一些繁重的数据集。

      如果您使用应用程序控制器将数据集存储在会话中,那么它将在需要时可供所有控制器使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 1970-01-01
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 2020-12-26
        • 2023-03-04
        相关资源
        最近更新 更多