C# asp.net如何在服务器中从HTML生成对象

C# asp.net如何在服务器中从HTML生成对象,c#,asp.net,server,C#,Asp.net,Server,我在asp.net中构建了一个有几个按钮的页面。 按钮在页面加载事件中动态创建。 在第一次加载页面(isPostBack=False)时,我给每个按钮一个文本,并将按钮添加到表单中。 在回发时(单击按钮后),我只向表单添加按钮。 此外,服务器还具有所有按钮的数组。 问题是-在回发时,服务器如何知道并为每个创建的按钮提供正确的文本值(仅在第一页加载时提供,但在回发时,在创建按钮之前,按钮数组为空) 这是一段代码片段- protected Button[,] buttons; Table t

我在asp.net中构建了一个有几个按钮的页面。 按钮在页面加载事件中动态创建。 在第一次加载页面(isPostBack=False)时,我给每个按钮一个文本,并将按钮添加到表单中。 在回发时(单击按钮后),我只向表单添加按钮。 此外,服务器还具有所有按钮的数组。 问题是-在回发时,服务器如何知道并为每个创建的按钮提供正确的文本值(仅在第一页加载时提供,但在回发时,在创建按钮之前,按钮数组为空)

这是一段代码片段-

protected Button[,] buttons;
    Table table;

    protected void Page_Load(object sender, EventArgs e)
    {
        buttons = new Button[4, 4];
        table = new Table();
        Form.Controls.Add(table);
        for (int i = 0; i < 4; i++)
        {
            TableRow row = new TableRow();
            table.Controls.Add(row);
            for (int j = 0; j < 4; j++)
            {
                TableCell cell = new TableCell();
                row.Cells.Add(cell);

                    buttons[i, j] = new Button();
                    //buttons[i, j].Attributes.Add("runat", "server");
                    buttons[i, j].Click += new EventHandler(b_Click);
                    cell.Controls.Add(buttons[i, j]);


            }
            //table.Controls.Add(row);
        }
        if (!Page.IsPostBack)
        {
            for (int i = 0; i < 4; i++)
            {
                createButtons(i);
            }
        }

    }

private void createButtons(int i)
    {
        for (int j = 0; j < 4 && i*j!=9; j++)
        {
            if (i * j == 9)
            {
                buttons[i, j].Width = 0;
                buttons[i, j].Height = 0;
            }
            Button b = buttons[i, j];
            buttons[i, j] = b;
            b.Height = 100;
            b.Width = 100;
            b.Font.Bold = true;
            b.Font.Size = FontUnit.XLarge;
            b.Text = randomNumber().ToString();
            b.BackColor = Color.FromArgb(r.Next(0, 255), r.Next(0, 255), r.Next(0, 255));

        }
    }
受保护按钮[,]按钮;
表格;
受保护的无效页面加载(对象发送方、事件参数e)
{
按钮=新按钮[4,4];
table=新表();
表单.控件.添加(表);
对于(int i=0;i<4;i++)
{
TableRow行=新TableRow();
table.Controls.Add(行);
对于(int j=0;j<4;j++)
{
TableCell=新的TableCell();
行.单元格.添加(单元格);
按钮[i,j]=新按钮();
//按钮[i,j].Attributes.Add(“runat”,“server”);
按钮[i,j]。单击+=新建事件处理程序(单击);
添加(按钮[i,j]);
}
//table.Controls.Add(行);
}
如果(!Page.IsPostBack)
{
对于(int i=0;i<4;i++)
{
(i);
}
}
}
私有void创建按钮(int i)
{
对于(int j=0;j<4&&i*j!=9;j++)
{
如果(i*j==9)
{
按钮[i,j]。宽度=0;
按钮[i,j]。高度=0;
}
按钮b=按钮[i,j];
按钮[i,j]=b;
b、 高度=100;
b、 宽度=100;
b、 Font.Bold=true;
b、 Font.Size=FontUnit.XLarge;
b、 Text=randomNumber().ToString();
b、 BackColor=Color.FromArgb(r.Next(0255),r.Next(0255),r.Next(0255));
}
}

此行为是asp.net的关键设计目标之一。微软希望asp.net的范例与桌面编程非常相似,这样人们就更容易过渡到使用web技术。其中一个关键部分是抽象web的无会话特性,这就是为什么asp.net在请求之间保留控件初始化

Asp.net通过几种方式实现这一点。最常见的是
ViewState
,它是整个页面控件树的base64编码,存储在隐藏的输入控件中,并在每次请求时发送给客户端。如果检查发送到浏览器的HTML,可以看到此字段

另一种机制称为
SessionState
,它存储在服务器端


Scott Mitchell有一篇关于视图状态内部工作原理的非常好的文章,您可以在这里阅读:

可能是视图状态。懒得检查自己,但您可以尝试禁用ViewState,看看它是否仍然有效。是的,您是正确的。如果ViewState=False,则按钮不接收文本值。但问题仍然是服务器如何知道按钮的值?服务器知道这个值,因为,这些值被发回服务器,如果你打开网络控制台,比如说在chrome中,检查请求负载,你可以看到整个控件都被发回-整个树肯定是不正确的。更像是“非默认值”(技术上也不正确)@Stilgar-是的,这有一些细微差别。技术上的答案是ViewState存储通过编程修改的控件的属性值。但是,如果以编程方式修改子控件,asp.net仍会生成一个树,以便正确定位修改后的控件。