Web服务器控件可以添加运行在服务器上的事件处理程序。如Button的Click事件、DropDownList的SelectedIndexChanged事件、TextBox的TextChanged事件。
当文本框内容发生了变化,TextChanged事件不会立即触发,只有点击了Submit按钮(回送),将表单提交给服务器,才会触发TextChanged事件。.NET运行库负责检测表单哪里发生了变化,应该执行哪个事件处理程序。
表单变化的判断是通过View State(一个隐藏字段)完成的。服务端把页面发给客户端时,View State和表单中的控件的值是一致的,当表单提交时,会将View State原封不动的传给服务端。
练习一:显示客户的输入
在上一节EventRegistration项目的基础上继续
1、Registration.aspx设计视图表格添加一行,在第二列添加一个Label,命名为:lblResult
2、双击Submit按钮,添加Click事件
<td>
<asp:Button ID="Submit" runat="server" Text="Button" onclick="Submit_Click" />
</td>
Registration.aspx.cs文件中添加相应事件处理程序代码:
protected void Submit_Click(object sender, EventArgs e)
{
string ddlEventVal = ddlEvent.SelectedValue;
string firstNameVal = tbFirstName.Text;
string lastNameVal = tbLastName.Text;
string emailVal = tbEmail.Text;
lblResult.Text = String.Format("{0} {1} selected the event {2}.",
firstNameVal, lastNameVal, ddlEventVal);
}
3、运行结果:
网页源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<style type="text/css">
.style1
{
width: 100%;
}
.style2
{
width: 100px;
}
</style>
</head>
<body>
<form method="post" action="./Registration.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTM4Mjc3NDY0NA9kFgICAw9kFgICCw8PFgIeBFRleHQFM+W8oCDkuIkgc2VsZWN0ZWQgdGhlIGV2ZW50IEludHJvZHVjdGlvbiB0byBBU1AuTkVULmRkZLLYsHTQ1y9m5IcS32nN77v5PTHgZ7Alu75++SBlh6P9" />
</div>
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="0E6B69E9" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEdAAixkD6aHbdQLjjDUgjFEXFtMTQJkvmQgAJqS9DcCRIg8889lYeFJo4C5E2Of0jt+xdqgRvUMSslP8U4uBbGrMF60fMME9lwpgVXR7Bj0XM58GPMnjboa62QCFz6XwjsGoCW9cfhXMGEAsxjutrqH9VId8BcWGH1ot0k0SO7CfuulDq5v0LIqY2I1pYYGuzc0SywXRcooJ7z4tb1NjDL16Il" />
</div>
<div>
<table class="style1">
<tr>
<td class="style2">
Event</td>
<td>
<select name="ddlEvent" id="ddlEvent" style="height:18px;width:141px;">
<option selected="selected" value="Introduction to ASP.NET">Introduction to ASP.NET</option>
<option value="Introduction to Windows Azure">Introduction to Windows Azure</option>
<option value="Begin Visual C# 2012">Begin Visual C# 2012</option>
</select>
</td>
</tr>
<tr>
<td class="style2">
First Name</td>
<td>
<input name="tbFirstName" type="text" value="张" id="tbFirstName" />
</td>
</tr>
<tr>
<td class="style2">
Last Name</td>
<td>
<input name="tbLastName" type="text" value="三" id="tbLastName" />
</td>
</tr>
<tr>
<td class="style2">
Email</td>
<td>
<input name="tbEmail" type="text" id="tbEmail" />
</td>
</tr>
<tr>
<td class="style2">
</td>
<td>
<input type="submit" name="Submit" value="Button" id="Submit" />
</td>
</tr>
<tr>
<td class="style2">
</td>
<td>
<span id="lblResult">张 三 selected the event Introduction to ASP.NET.</span>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
Fiddler抓包:
在Fiddler中抓到的Post包中可以看到View State相关的参数。
4、关于运行机制的猜测
查看Submit_Click事件处理程序中参数和元素值的获取,貌似服务器中元素的值并不是通过Post参数获取的。那.NET是通过什么方法传递元素值的?如果Post不传递Fiddler中抓到的Post参数并没有关系。
protected void Submit_Click(object sender, EventArgs e)
{
string ddlEventVal = ddlEvent.SelectedValue;
string firstNameVal = tbFirstName.Text;
string lastNameVal = tbLastName.Text;
string emailVal = tbEmail.Text;
lblResult.Text = String.Format("{0} {1} selected the event {2}. e内容{3}",
firstNameVal, lastNameVal, ddlEventVal, e.ToString());
}
用PostMan正常向服务端传递参数:
此时返回信息正常。
用PostMan少发送几个参数时, Submit_Click事件处理程序 没有从元素中获取到相应值:
推断:客户端通过Http向服务端发送请求,.NET接受到请求后先根据参数将相关元素设置为指定状态,然后通过对比View State判断调用哪个事件处理函数。在事件处理函数执行时,相关元素值已经被设置成了参数指定的结果。