ASP.Net 随想-服务器控件的页面请求模型

翻译|其它|编辑:郝浩|2007-07-02 10:47:08.000|阅读 2338 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

传统的 WEB 编程能引起页面表单提交的元素为:

INPUT type=submit
元素 | input type=submit 对象
创建一个按钮,该按钮单击后将提交表单。
INPUT type=image
元素 | input type=image 对象
创建一个图像控件,该控件单击后将导致表单立即被提交。

还有一个提交 From 的方法:
submit;

  
相信我不解释你也知道这个的方法的用法!!好的,看看 Asp.Net 生成的页面文件,是不是能逃脱这个宿运?随便 Create 一个工程,拖一个服务器控件 button 进来,运行,看生成的客户端代码:怎么样?看出来倪端吧?

<asp:Button ID="btnTest" runat="server" OnClick="btnTest_Click" Text="   " />

被解释(应该叫编译)成

<input type="submit" name="btnTest" value="   " id="btnTest" />

其实所有的服务器控件都会生成类似这样的客户端代码,服务器控件是微软的一大创举,颠覆了传统的WEB 的开发模式,创造性地应用了经典 C/S 事件驱动模式,天然的是 Asp.Net 模型符合 MVC 模式!

呵呵,Net 如何把服务器控件 Button 解释成上述客户端的呈现哪?Good!请看微软实现 Button 的代码:
首先构造函数继承基类如下:

public Button() : base(HtmlTextWriterTag.Input)
{
  }

说明他首先在客户端生成一个<input>元素,再看:

protected override void AddAttributesToRender(HtmlTextWriter writer)
{
   
bool useSubmitBehavior = this.UseSubmitBehavior;
   
if (this.Page != null)
    {
        
this.Page.VerifyRenderingInServerForm(this);
    }
   
if (useSubmitBehavior)

 {
     writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
  }
 
else
 {
     writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
 }
 
//省略了其他代码…………………………………………………….
    
base.AddAttributesToRender(writer);
}


注意 useSubmitBehavior,这个是 button 属性:表示是否这个按钮呈现为提交按钮(说白了是否设定input

type 是否为 sumbit)!默认情况下是TRUE

代码如下:

sumbit writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");


完成一系列其他的修饰后在调用基类的 AddAttributesToRender(writer)

呵呵,如果你是细心的人,你会注意到上面我们说过 useSubmitBehavior,它默认是 True,你会说,如果我把他设成 False,他生成的客户端元素<inpput>的代码属性不再会是 submit,而是 button,而这个属性点击后不会触发表单提交!看看微软如何解决这个问题的。好,还是先看客户端代码:

<asp:Button ID="btnTest" runat="server" OnClick="btnTest_Click" Text="   " UseSubmitBehavior="False" />


被解释(应该叫编译)成

<input type="button" name="btnTest" value="   " onclick="javascript:__doPostBack('btnTest','')" id="btnTest" /> 


注意到有什么变化吗?客户端多了 onclick="javascript:__doPostBack('btnTest','')",我塞

你真牛,这都被你看出来了!在看看服务器端多了什么?UseSubmitBehavior="False",呵呵,又被你看出来了!

那么这两者肯定有必然的联系!靠,这个你又猜到了!I Flow You!这个放后再说,先看下面:

既然客户端多了一个

onclick="javascript:__doPostBack('btnTest','')"

那客户端肯定存在__doPostBack(Argumen1, object Argument1) ,仔细看下你生成的页面代码:

是不是有这段代码存在:

<script type="text/javascript">
<!--
var theForm = document.forms['form1'];
  
if (!theForm) {
        theForm = document.form1;

}
function __doPostBack(eventTarget, eventArgument) {

    if (!theForm.onsubmit || (theForm.onsubmit() != false))  {

    theForm.__EVENTTARGET.value = eventTarget;

theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// -->
</script>

先解释下,__doPostBack 就是触发表单提交的客户端函数,参事一是触发事件的控件,参数二十事件的所带的参数!__EVENTTARGET EVENTARGUMENT 为隐藏的 Input 元素!!

这段代码如何生成的哪?回去再看 Button 的实现代码:

protected internal override void OnPreRender(EventArgs e)

{

//…….省略其它代码

else if (!this.UseSubmitBehavior)

{

this.Page.RegisterPostBackScript();

}

}

注意  this.Page.RegisterPostBackScript();这个就是罪魁祸首了! 

还有一个问题没有解决:onclick="javascript:__doPostBack('btnTest','')"如何由UseSubmitBehavior="False"生成的过程哪?

protected override void AddAttributesToRender(HtmlTextWriter writer)

{

//……省略了其他代码:

if (isEnabled)

{

firstScript = Util.EnsureEndWithSemiColon(this.OnClientClick);

if (base.HasAttributes)

{

string text3 = base.Attributes["onclick"];

if (text3 != null)

{

firstScript = firstScript + Util.EnsureEndWithSemiColon(text3);

base.Attributes.Remove("onclick");

}

}

}

if (this.Page != null)

{

string secondScript = this.Page.ClientScript.GetPostBackEventReference(postBackOptions, false);

if (secondScript != null)

{

firstScript = Util.MergeScript(firstScript, secondScript);

}

}

if (this.Page != null)

{

this.Page.ClientScript.RegisterForEventValidation(postBackOptions);

}

if (firstScript.Length > 0)

{

writer.AddAttribute(HtmlTextWriterAttribute.Onclick, firstScript);

if (base.EnableLegacyRendering)

{

writer.AddAttribute("language", "javascript", false);

}

}

//…..省略了其他代码

}

首先检测如果启动控件,首先去掉基类的"click"Attributes!然后合并积累和客户设置的客户端事件,然后再生成 onclick="javascript:__doPostBack('btnTest','')客户端属性,如下:

writer.AddAttribute(HtmlTextWriterAttribute.Onclick, firstScript);

if (base.EnableLegacyRendering)

{

writer.AddAttribute("language", "javascript", false);

}

好了,至此,你应该知道 Asp.Net 的如何和服务器交互了,别管怎么复杂的控件都是通过如上方法进行提交表单的!

PS:这个是我在出差南京路上写的,比较匆忙,通过我的这三篇文章,你应该知道 Asp.Net 向的数据项并知 Asp.Net 在豪华的外衣下和服务器交互的原始手段的对应得方法,其实服务器空间之所以强大,Asp.Net 编程模型的成功还离不开一位功臣,那就是 ViewState,呵呵,直到我的下篇随想是什么了吧!


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:csdn

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP