Asp.net mvc ASP.NET MVC:保存用户正在编辑的实体的位置

Asp.net mvc ASP.NET MVC:保存用户正在编辑的实体的位置,asp.net-mvc,domain-driven-design,Asp.net Mvc,Domain Driven Design,这里有一个简单的问题:用户希望以类似网格的方式编辑产品:选择并单击添加,选择并单击添加。。。他们看到更新的产品列表。。。然后单击“完成”,应保存订单 但是,每个“添加”都必须转到服务器,因为它涉及服务器端验证。此外,验证在域实体(比如Order)内——也就是说,为了进行验证,我需要调用Order.Add(product),然后Order决定是否可以添加产品 问题是,如果我将产品添加到订单中,它会保持更改,因此即使用户不单击“完成”,更改仍将存在 好的,在用户单击Finish之前,我可能不应该修改

这里有一个简单的问题:用户希望以类似网格的方式编辑产品:选择并单击添加,选择并单击添加。。。他们看到更新的产品列表。。。然后单击“完成”,应保存订单

但是,每个“添加”都必须转到服务器,因为它涉及服务器端验证。此外,验证在域实体(比如Order)内——也就是说,为了进行验证,我需要调用Order.Add(product),然后Order决定是否可以添加产品

问题是,如果我将产品添加到订单中,它会保持更改,因此即使用户不单击“完成”,更改仍将存在

好的,在用户单击Finish之前,我可能不应该修改订单。但是,如何验证产品呢?这应该由订单实体完成-如果产品已经添加,如果产品与其他产品不冲突,等等

另一个问题是,我必须将产品添加到订单中,并根据其新状态“重建视图/HTML”(因为它可能会发生很大变化)。但是如果我不坚持订单更改,下一次添加将从每次相同的订单开始,而不是从更新的订单开始。也就是说,我需要以某种方式跟踪订单的更改

我看到了几种解决方案:

  • 每次用户单击“添加”,从数据库中检索订单,并添加所有新产品(从页面),但不要将其持久化,只返回视图(订单)。问题是我无法从POST/Edit重定向到GET/Edit,因为所有数据都只存在于POST数据中,并且GET/Edit会丢失它。这意味着刷新页面的工作方式不好(F5会导致重复的请求,更不用说浏览器的对话框了)。
    • 嗯,我想我可以使用TempData(和MvcContrib助手)重定向到GET。因此,在POST to/Edit之后,我处理业务逻辑,获取新数据以供查看,并从MvcContrib执行重定向到操作(数据),该操作通过TempData传递数据。但是由于TempDate是。。。临时雇员F5之后,所有数据都将丢失。不起作用。该死的数据应该存储在某个地方,这样或那样
  • 将“编辑对象”和POST数据(订单、新产品信息)存储在会话中。这也可以是数据库。“当前项目-每页类型”的类型。因此,页面将从该存储获取订单ID和当前添加的产品。但是从多个页面编辑是有问题的。我不喜欢在会话中存储临时/当前对象
  • 将产品标记为“已确认”-如果我们进行/订购/展示,我们首先从订单中清除所有未确认的产品。丑陋而混乱的逻辑
  • 制作订单副本-临时订单-并制作/编辑订单。确认将把更改从临时订单移动到持久化订单。很多难看的工作
  • 也许是一些AJAX魔术?例如,“添加”按钮不会重新加载页面,但只会将新的+已添加的产品发送到服务器,服务器将验证为订单。添加(产品+新产品)但不会持续更改,只会返回更新的订单信息以重新构建网格。但是刷新/F5将删除所有用户输入的信息
  • 还有什么

  • 这个问题常见吗?如何解决类似的问题?最佳实践是什么?

    这在很大程度上取决于您如何实现您的对象/验证,但您的选项5可能是最佳方案。如果您不喜欢AJAX,那么可以通过将已添加但未保存的条目的相关数据写入隐藏字段来完成相同的任务

    换言之,流的结尾是这样的:

  • 用户输入一个项目

  • 项目被发送到服务器并进行验证。返回视图时,用户在隐藏字段中输入数据

  • 用户输入第二项

  • 项目被发送到服务器,并对两个项目进行验证。该视图将返回隐藏字段中两个项目的数据

  • 等等

  • 就F5/刷新输入的数据而言。。。根据我的经验,这不是什么大问题。一个更紧迫的问题是后退/前进按钮,它需要像真正简单的历史记录一样进行管理

    如果要使页面在刷新后继续工作,则需要执行以下操作之一:

  • 将记录持久化到数据库中,以某种方式与当前用户关联
  • 将记录保存到会话
  • 将记录保留到查询字符串中

  • 这些是唯一可以通过重定向和刷新保持的存储位置。

    如果我是你,我会想出类似选项5的方法。既然你说你对Ajax很满意,你可以试试这个。但在执行此操作之前,应该将验证逻辑移到Order.Add()方法之外。也许您可以将其移动到另一个名为Validate()的公共函数,该函数返回bool。您仍然可以在Add()方法中调用相同的Validate(),从而在添加订单之前进行必要的验证

  • 尝试在客户端进行验证。如果您使用的是jQuery,那么可以使用jQuery验证插件。但是,如果由于某种原因(例如,当您需要根据数据库验证内容时)这是不可能的。您应该在服务器端进行验证,只返回一个带有“success”布尔标志的JSON对象和一条可选消息,这是一种标记数据有效的方法。只有在上一个订单有效的情况下,您才允许用户添加新产品
  • 当用户点击finish时,将产品发送到服务器并再次进行验证,但在这个往返过程中保持订单

  • 现在,如果我对此有完整的发言权,我甚至不会在添加/编辑产品时进行验证。只要客户点击finish,我就会进行验证。这将是最简单的解决办法。但是,也许我遗漏了一些东西。

    Ajax是我的拿手好戏,我不需要隐藏,我需要的是