2

我目前正在使用 mvc 3 和 c# 开发应用程序。我需要实现一个控制器来上传文件。我有一个 db 表,用于存储文件元数据、名称、大小、类型、文件路径、用途等。我想将实际文件作为 blob 存储在 Windows azure 服务器上,并使用 db 行作为指向它的指针.

我想保存连接到文件的项目,例如Person Profile(目的),然后在我获得配置文件的主键后执行上传,以便我可以进行必要的关联,然后上传文件并保存文件的元数据。

如果用户可以在按下按钮保存配置文件页面之前选择文件,我如何使这个原子化。

在完成其余步骤之前,似乎我必须以某种方式将文件写入会话变量或将文件写入某个临时文件夹(暂存)。有没有更好的方法来执行这些可以保证原子性的步骤?

4

3 回答 3

6

恕我直言,问题在于架构师将此过程视为原子操作,而用户体验则不然。你身处冲突的中心。=)

您可以保证两个不同进程的原子性和数据统一后处理。让我做一些疯狂的猜测,假设您正在为当前(交互式)用户实现配置文件创建过程。

  • 允许用户上传其图片;将其提交到您的存储中,将其标记为事务性,将 SessionID 元数据添加到其中。

  • 用户完成创建他/她的个人资料后,扫描您的存储以查找具有相同 SessionID 的图片。将两者绑定在一起(例如,将文件 ID 与配置文件 ID 相关联。)一个更复杂的过程将包括,例如,一个“配置文件创建”cookie,它应该存储一个独占 ID - 所以如果用户放弃该会话并且稍后返回上传的文件仍然可以使用。

  • 实施“垃圾收集器”。在达到阈值(时间或其他时间)后处理未使用的文件。

我知道这些建议并不完全涵盖您最初的要求,但它们可能有助于简化您的实施。

于 2013-08-17T16:05:09.837 回答
1

你用的是什么数据库?您可以通过使用SQLTransaction 类包装您的插入以在 try / catch 中获取主键,使用SqlTransaction.Rollback 方法SqlTransaction.Commit 方法来撤消插入(如果使用文件传输

try
{
 // conn.BeginTransaction();
 // Insert
 // File Transfer
 // Catch Exceptions
 // transaction.Commit();
}
catch (Exception ex)
{
  // Roll back Insert if file transfer fails
  // transaction.Rollback();
}
于 2013-08-14T17:38:46.820 回答
0

从你遇到麻烦的问题中不清楚。

如果您将 htmlmultipart/form-data表单发布到控制器,则该文件将与其余数据一起作为一个请求发布。当你准备好对文件的数据做一些事情时,你只需访问HttpPostedFileBaseInpustStream的属性,我假设你已经自动绑定到某个地方。无需保存临时文件,IIS 已经为您做到了。

另一方面,如果您想确保在上传任何数据之前创建配置文件,那么您需要使用单独的 HTTP 请求来处理它(但这与原子操作相反,所以我假设这不是你需要的。)

如果您想要处理文件成功上传但服务器检测到表单的其他部分存在问题的情况,并且您不希望用户必须等待文件再次上传,是的,您将希望将对该文件的引用临时保存在某处,以便它不会在请求之间丢失(如会话变量或写回表单上的隐藏字段)。

于 2013-08-13T05:19:30.453 回答