【问题标题】:TryUpdateModel does not update anything for FormViewTryUpdateModel 不会为 FormView 更新任何内容
【发布时间】:2026-01-30 00:25:01
【问题描述】:

我正在使用 Framework 4.5,并决定利用它的一些改进.. 假设我在 FormView 中有以下控件:

<asp:TextBox ID="EventNumberTextBox" runat="server" Text='<%# Item.Event_Num %>' />

在我的 UpdateMethod 中,我做了以下操作:

public void UpdateModelFromView(int? ID)
{
    var modelView = new AlertMessageController().LoadById(ID);
    var updateSuccess = TryUpdateModel(modelView);
    if (updateSuccess)
    {
        new AlertMessageController().Save(modelView);
        RedirectToViewPage();
    }
}

问题在于,尽管 Form 集合确实包含我所做的所有更改——在给定的情况下,我已将 Event_Num 设置为某个值——但这些更改并未反映到 modelView。换句话说,我对 FormView 控件所做的任何更改都将被忽略,并且模型在加载后按原样保存...

【问题讨论】:

  • 您是否尝试过在 TextBox 上使用 BindItem 而不是 Item,即 BindItem.Event_Num?
  • 格雷厄姆,非常感谢,我觉得我快到了,但现在又遇到了另一个问题。问题是我必须只从表单中获取字段并忽略 URL。当我只使用一个参数的 TryUpdateModel 时 - 它使用 URL 和表单参数更新模型。我尝试使用第二个参数:new NameValueCollectionValueProvider(HttpContext.Current.Request.Form, Culture.GetBrowserOrDefaultCulture()) 或 new FormValueProvider(Page.ModelBindingExecutionContext),但在这些情况下 TryUpdateModel 会完全忽略所有更改的值...
  • 我已尝试更改 UpdateMethod 的参数以接受完整对象:UpdateModelForView(AlertMessageInfo item)。现在 ModelState 似乎包含表单中的所有键,但是......当我尝试使用 TryUpdateModel(modelView, new FormValueProvider(Page.ModelBindingExecutionContext)) 时,它的值未应用
  • 太好了,你正在取得进展。 Web 窗体数据绑定不从 Url 获取值(只有 MVC 数据绑定会这样做)。 Web 窗体数据绑定只会从指定了 BindItem 的 FormView 控件中获取值。没有看到更多你的代码,我不知道到底出了什么问题。
  • 现在可以使用 BindItem 而不是 Item 和 TryUpdateModel(modelView) - 只有一个参数。如此简单:) 但是现在我很好奇,为什么当我使用第二个参数作为 new FormValueProvider(Page.ModelBindingExecutionContext) 时它不起作用?

标签: asp.net model formview


【解决方案1】:

Item 仅用于单向数据绑定。对于双向数据绑定,您应该使用 BindItem,即 BindItem.Event_Num。

【讨论】:

  • 是的,我明白了。我只是想不通,为什么使用 TryUpdateModel(modelView, FormValueProvider(Page.ModelBindingExecutionContext)) 与 TryUpdateModel(modelView) 的工作方式不同。在我看来,它应该是一样的......
  • 还有一个问题。如果我需要使用 UpdatePanel - 如何访问项目?在这种情况下,它们确实超出了可见性范围!
  • Web 窗体在数据绑定时不使用 FormValueProvider。 FormValueProvider 用于 MVC,其中输入的名称与模型属性的名称匹配。
  • 好的。谢谢你。然后我还有一个问题:) 在某些情况下,我需要在实际更新数据库之前更改 Update 方法中的值。但是当我尝试使用序列时: Page.ModelBindingExecutionContext.ModelState.Remove("Alert_Id"); Page.ModelBindingExecutionContext.ModelState.SetModelValue("Alert_Id", ....); - 模型确实更新了这些参数。但是,TryUpdateModel(modelView) 完全忽略了这些新值...我是否需要始终在 Update 方法中更新源项参数?
  • 调用TryUpdateModel后直接在模型上更新值,即TryUpdateModel(modelView); modelView.Name = "改名";
【解决方案2】:

Anik,我认为表单字段名称需要与属性名称匹配。

【讨论】:

  • 我当然试过了。不走运:(我也尝试过使用另一个版本的 TryUpdateModel 方法:TryUpdateModel(modelView, new NameValueCollectionValueProvider(HttpContext.Current.Request.Form, Culture.GetBrowserOrDefaultCulture())) - 也不走运。
  • 但是等一下:你是说名字吗?那么,除了ID之外,我还需要为每个表单控件添加一个名称吗?我暂时无法尝试,但我很好奇..
  • 当 ASP.NET 为 TextBox 生成 Html 时,它会根据 ID 自动为其创建一个名称。该名称需要与属性名称匹配。如果您使用 HtmlHelpers 生成表单和输入字段,它会为您处理。
  • 是的,名称已分配,与ID相同。问题是,即使 ClientIdMode 设置为静态 - 总体而言,ID 看起来像这样:“ctl00$cphMain$ctl00$ctl00$FormView$Event_Num”而不是我指出的简单的“Event_Num”。这是一个常见的 ASP.NET 标记——我们在当前项目中不使用 MVC 和 Razor 或其他类似的东西,所以没有任何 HtmlHelpers。所以...不知道还有什么可以尝试的。
  • 他们确实在 4.5 中将 ModelBinding 添加到 WebForms,但我没有使用它。根据 MSDN:只能从由数据绑定控件的 UpdateMethod 或 InsertMethod 属性指定的方法调用此方法。有关将模型绑定与 Web 表单结合使用的教程系列,请参阅link
【解决方案3】:

不幸的是,他们的例子非常狭窄。我下载下来分析一下。他们没有演示 FormView 更新方法,只有网格,所以我不知道 FormView 控件的 ID 和 NAME。我认为绑定值应该足以设置与实际属性的对应关系以进行更新(即 Item.Event_Num)。还有一件更奇怪的事情:当我单击 TryUpdateModel 方法时 - 它会将我带到 UserControl,但它没有显示该方法的描述!但是我确实安装了 FrameWork 4.5,并且我的文档取自在线源...

【讨论】: