ASP.. NET 4.5 TryUpdateModel在使用母版页的WebForm中不选择表单值

本文关键字:WebForm 选择 表单 母版页 NET TryUpdateModel ASP | 更新日期: 2023-09-27 18:07:31

我正在使用WebForms,我试图在一个母版页内执行模型验证,由于某种原因,模型没有拾取值,这意味着在验证触发后,如果我输入一个好的值,模型会一直返回空,因此一遍又一遍地触发验证。如果我把代码在页没有母版页它工作得很好。我可以举一个非常简单的例子,老实说,很难相信MasterPages如此常见,到目前为止还没有人遇到过这种情况。出于本例的目的,我将模型嵌入到后面的代码中,但是拥有外部没有什么不同。任何想法都是非常受欢迎的。谢谢。

——主页

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="test.master.cs" Inherits="test" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder id="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

—WebForm—

<%@ Page Title="" Language="C#" MasterPageFile="~/test.master" AutoEventWireup="true" CodeFile="test3.aspx.cs" Inherits="test3" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <div>
        <asp:ValidationSummary ID="valSummary" runat="server" />
    </div>
        <div><label>First Name:</label></div>
        <div><input type="text" id="FirstName" runat="server" /></div>
        <div><label>Middle Name:</label></div>
        <div><input type="text" id="MiddleName" runat="server" /></div>
        <div><label>Last Name:</label></div>
        <div><input type="text" id="LastName" runat="server" /></div>
    <div>
        <asp:Button ID="btnSubmit" runat="server"  Text="Submit" />
    </div>
</asp:Content>

——代码隐藏——

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.ModelBinding;
using System.ComponentModel.DataAnnotations;

public partial class test3 : System.Web.UI.Page
{
    public class testClass2
    {
        [Required()]
        [MinLength(2)]
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        [Required()]
        [MinLength(2)]
        public string LastName { get; set; }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack)
        {
            testClass2 tc = new testClass2();
            if (TryUpdateModel(tc, new FormValueProvider(ModelBindingExecutionContext)))
            {
                System.Diagnostics.Debug.WriteLine("test");
            }
        }
    }
}

ASP.. NET 4.5 TryUpdateModel在使用母版页的WebForm中不选择表单值

这个问题确实是由使用母版页引起的。当在数据绑定控件之外使用时(如GridView, FormView, Menu等),FormValueProvider期望在Request.Form字典中具有与模型对象中的属性名称相同的键。

如果你仔细看看生成的HTML,你会发现所有的input标签的形式有母版页的name属性值设置为类似ctl00$ContentPlaceHolder1$FirstName, ctl00$ContentPlaceHolder1$LastName等,而没有母版页的形式留下名称属性完整,等于控件的ID属性值。

这就是如何生成UniqueID以避免名称重复的方式(这应该避免,因为在Web表单中我们只能有一个form标签,因此在母版页和表单页上都有相同的ID's控件)。

这就是为什么FormValueProvider无法获得testClass2对象的值的原因,它只是无法找到FirstName, LastName, MiddleName的值。

我找到了一个解决方案。您可以编写一小段前端代码,将name设置为id,不要忘记将ClientIDMode设置为Static

<script>
    $("input[type=text]").each(function () {
         var id = $(this).attr("id");
         $(this).attr("name", id);
    });
</script>