【问题标题】:MVC Html.textbox/dropdown/whatever won't refresh on postbackMVC Html.textbox/dropdown/whatever 不会在回发时刷新
【发布时间】:2010-06-17 23:00:36
【问题描述】:

好的,让我们从 Html.Textbox 开始。它应该包含从文件中读取的文本。文件读取基于用户从下拉列表中选择的内容。

第一次还好。用户从下拉列表中选择一个值。控制器使用该值从文件中读取一些文本,并通过视图模型将该文本返回给视图。一切都很好。

然后用户从下拉列表中选择另一个值。控制器从文件中读取一个新值并通过视图模型返回它。调试到视图中设置 HTML.TEXTBOX 之前的 LINE 表明模型包含正确的值。但是,当页面显示时,文本框本身仍然显示 PREVIOUS 值!

如果我从 Html.Textbox 切换到纯输入 type="text" html 控件,一切正常。这并不难,但我的下拉列表也会发生同样的事情——我无法在代码中设置选定的值。它总是恢复到最后选择的任何内容。使用动态生成的选项列表呈现“选择”标签是一件很痛苦的事情。我希望能够使用 Html.Dropdown。

我在这里错过了什么?这在网络表单中是如此简单!

【问题讨论】:

  • 我也有同样不直观的行为。模型肯定是它应该渲染的,而 HtmlHelper 应该渲染模型?如果 Model.CaptchaAttempt == "" 在 Html.TextBoxFor(m=>m.CaptchaAttempt) 运行之前,它肯定应该呈现一个空值的文本框吗?你解决问题了吗?
  • 我确实找到了答案——我创建了另一个线程 (stackoverflow.com/questions/3444994/…),因为我想我已经忘记了这个问题。我将 ModelState.SetModelValue 用于我想设置为空白或某种状态的字段。一些评论者认为我应该做 RedirectToAction,但我回答说我希望能够向用户显示确认消息,这需要重新显示相同的视图。我认为确认消息很重要,所以我就这样做了,尽管它可能不是最佳实践。

标签: asp.net-mvc-2 postback html-helper


【解决方案1】:

当您发布表单时,发布的值将放入ModelState。当HtmlHelper 呈现一个 html 输入元素时,例如Html.TextBoxFor(x => x.FirstName),它将搜索各个位置以获取文本框的值...ModelState 在位置列表中位于 ViewData.Model 之前。因此,之前发布的值将出现在您的文本框中。

要解决此问题,您可以清除 ModelState 值或更新 ModelState 值。但我有点认为这是解决问题的一种老套方法。

真正的问题更多地与帖子和请求的流动有关。我个人会对此进行研究,并可能实施 PRG(Post Redirect Get)模式。

HTH,
查尔斯

【讨论】:

    【解决方案2】:

    按照 Charles/Charlino 的说法:

    模型绑定更新 ModelState 对象,其中包含模型绑定期间收集的验证和模型绑定错误。

    在动作方法中,模型绑定已经发生以更新模型,并生成ModelState 对象。如果您现在在操作中更新模型上的值,您还必须手动更新模型状态(因为帮助程序使用它来生成他们的 HTML)。下面是一个例子:

    model.CaptchaIsValid = CaptchaService.ValidateAndExpireCaptcha(model.CaptchaAttempt);
    if (!model.CaptchaIsValid)
    {
        ModelState.AddModelError("CaptchaAttempt", "Incorrect - please try again");
    }
    
    // I'll clear the value on each attempt, to force them to re-enter a CAPTCHA.
    model.CaptchaAttempt = string.Empty;
    
    // Since I updated the model, I must create a new ValueProvider result...
    ValueProviderResult clearedValue = new ValueProviderResult(
          model.CaptchaAttempt, 
          model.CaptchaAttempt, 
          CultureInfo.CurrentCulture);
    
    // ... and update the ModelState's value.
    ModelState.SetModelValue("CaptchaAttempt", clearedValue);
    

    【讨论】:

      【解决方案3】:

      我在这里看到的最大问题是您试图在 MVC 中进行回发。该模型确实不受支持,并且实际上比其价值要麻烦得多(您似乎正在发现)。我建议使用 Ajax 动态更新下拉列表的内容。

      【讨论】:

      • 我非常不同意。你可以在 MVC 中做任何可以用普通 HTML 做的事情,包括回发。但是,正如我发现的那样,如果您想以编程方式设置控件的值,则不能使用 HTML 助手。但是我写了几乎一整个没有 AJAX 的应用程序,完全可以做到。
      • POST 是一种 HTTP 事物,不特定于 MVC 或 WebForms。 AJAX 是浏览器的扩展,用于异步执行 POST(和其他请求)。您所指的“回发”可能是 WebForms 回发,其中 ViewState 来回发送。 MVC 并不意味着您必须手动维护状态,无论是通过标准的 HTTP POST 还是异步的……也就是说,我也非常不同意。
      猜你喜欢
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 2021-03-12
      • 2012-07-29
      • 2022-08-11
      相关资源
      最近更新 更多