【问题标题】:How to preserve text during a postback with ASP.NET MVC 3如何使用 ASP.NET MVC 3 在回发期间保留文本
【发布时间】:2011-10-15 00:31:01
【问题描述】:

我有一个产品编辑屏幕。用户可以选择产品的供应商。为此,我显示了一个 jQueryUI 对话框,允许他们浏览并选择供应商。当用户选择供应商时,我会更新页面上隐藏的 VendorID 输入,这是我的页面模型的一部分。我还用他们选择的供应商的详细信息更新了几个 div。这些仅用于显示目的 - 仅需要 id 来保存所选供应商。

这一切都很好而且很花哨,除非回发出现错误,在这种情况下,我会重新显示相同的视图。 ModelState 负责保留我所有的表单字段(包括隐藏的 VendorID)。但是,我的带有供应商文本的 div(当然)是空的,因为它们没有发布到服务器。

我首先为每个供应商显示字段创建隐藏字段并将它们放在模型上。然后隐藏字段在回发后仍然存在,但这并不能解决实际在屏幕上重新显示文本的问题。

我能想到的三个选项是:

  1. 在回发时,如果出现错误,请转到数据库,使用提供的 VendorID 获取 Vendor,然后使用我要显示的文本重新填充模型。
  2. 使用 RenderAction 并有一个操作来呈现所选供应商的详细信息。
  3. 使用只读文本框而不是 div 来显示供应商详细信息。

这些对我来说都不是很满意。我觉得我可能错过了一个明显的解决方案。有没有更好的解决方案?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    我建议您不要将额外的供应商信息作为主页的一部分。创建一个 JavaScript 函数 showVendorInfo()。调用时,如果 VendorID 隐藏输入具有值,它会通过 AJAX 获取相关的 Vendor 信息并使用 AjaxGetVendorInfo 操作方法显示它。从两个地方调用这个函数:

    • 在 document.ready() 中
    • 使用 jQueryUI 显示选择供应商后。

    现在,这将是一个动作方法。如果您希望您的用户有延迟问题,您可以执行以下操作以避免一些 a​​jax 调用: 在视图中检查您是否知道 VendorID;如果是这样,请调用 Html.RenderAction 从视图中调用相同的 AjaxGetVendorInfo 操作方法。

    这样做的好处是它避免了我发现的一个大禁忌:在 ViewModel 中包括仅显示值和模型绑定值。这使得 ViewModel 非常混乱,尤其是在存在验证错误时。 [开始使用肥皂盒] 最好让您的 ViewModel 仅具有用于模型绑定的属性,用于您的状态。将列表值、额外显示信息等放入 ViewData 或通过 AJAX 显示。

    【讨论】:

    • 这听起来确实像一个干净的解决方案,利用 ajax 来获取显示数据。与此解决方案略有相关,如果该数据来自数据库,您可以在服务器端使用 TempData 来缓存数据库结果。这也避免了额外的数据库之旅。
    • @Patrick 我喜欢你的方法。我尝试像您在页面加载时建议的那样使用 RenderAction 来避免 AJAX 调用,但其中一个问题是,如果在添加新产品时回发出错,则 VendorID 不在模型中。因此,我不能只使用模型上的 VendorID 调用 RenderAction,而无需进入 ModelState 来获取它,这对我来说似乎是一种 hack。关于如何最好地处理这种情况有什么想法吗?
    • 我误解了你在做什么,只是不知道在哪里。您在 ViewModel 上有一个 VendorID 属性,对吗?因此,用户提交表单,并且 VendorID 应该存在于模型绑定的 ViewModel 中。在 post action 方法中,在由于模型状态错误返回视图之前,您可以向 ViewModel 对象询问 VendorID,对吗?当您在出现验证错误时返回 View 时,是否传递您通过模型绑定获得的同一 ViewModel 对象?
    • (cont) 关键是不要将 ViewModel 视为 Get 操作方法以及视图最初需要显示的所有内容。 ViewModel 的存在是为了维护整个生命周期的状态。 VendorID 应该在那里,即使当有人新鲜访问页面时它总是空白。
    • 如果添加时出错,我会创建一个新的 ViewModel 实例。我这样做主要是因为 ViewModel 需要重新填充其选择列表。但这也解释了为什么我没有 VendorID。产品没有保存,所以当我重新创建 ViewModel 时,VendorID 恢复为默认值。我想这说明了您的建议,即 ViewModel 仅具有模型绑定的属性。我很想听听您对此的推理。我一直认为视图所需的一切都应该放在强类型的 ViewModel 中,但我可以被说服否则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2010-09-12
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 2011-08-07
    • 2011-11-01
    相关资源
    最近更新 更多