服务器控件和html控件区别

相关网盘免费资源下载...

 

服务器控件是否必须在 runat=server 的 Form 内?

对这个概念很多人有误解。以为凡是 WebControl 都必须放在 <form runat="server"></form> 里面。

(为了说明方便,以下仅列出 aspx 文件中 body 里的内容。)
1,

<form id="Form1" method="post" runat="server">
</form>   
<asp:TextBox ID="txtHello" Runat="server" Text="OK"></asp:TextBox>


2,

<form id="Form1" method="post" runat="server">
</form>   
<asp:Label ID="lblHello" Runat="server" Text="Hello"></asp:Label>


3,

<form id="Form1" method="post" runat="server">
</form>   
<asp:Button ID="btnHello" Runat="server" Text="Hello"></asp:Button>


结果发现了什么?

Label 可以正常使用。而 TextBox 和 Button 都会出现抛出一个异常。

因为 Label, Button, TextBox 都继承自 System.Web.UI.WebControls.WebControl 类。下面我们用 Reflector 来分析一下。
(如果不了解 Reflector 的可用 google 搜索).

WebControl 类的部分代码:

// (Attributes 省略)
public class WebControl : Control, IAttributeAccessor
{
    // 

    protected override void Render(HtmlTextWriter writer)
    {
          this.RenderBeginTag(writer);  // here
          this.RenderContents(writer);
          this.RenderEndTag(writer);
    }
     
    public virtual void RenderBeginTag(HtmlTextWriter writer)
    {
          this.AddAttributesToRender(writer);  // here
          HtmlTextWriterTag tag1 = this.TagKey;
          if (tag1 != HtmlTextWriterTag.Unknown)
          {
                writer.RenderBeginTag(tag1);
          }
          else
          {
                writer.RenderBeginTag(this.TagName);
          }
    }
}


Button 类的部分代码:

// (Attributes 省略)
public class Button : WebControl, IPostBackEventHandler
{
    // 

    protected override void AddAttributesToRender(HtmlTextWriter writer)
{
          if (this.Page != null)
          {
                this.Page.VerifyRenderingInServerForm(this); // here
          }
            //  .

          base.AddAttributesToRender(writer);
    }

    void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
    {
          if (this.CausesValidation)
          {
                this.Page.Validate();
          }
          this.OnClick(new EventArgs());
          this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
    }
}


TextBox 类部分代码:

// (Attributes 省略)
public class TextBox : WebControl, IPostBackDataHandler
{
    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        int num1;
        if (this.Page != null)
        {
            this.Page.VerifyRenderingInServerForm(this); // here
        }
        writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
        TextBoxMode mode1 = this.TextMode;

        // 
    }
}


Label 类部分代码:

// (Attributes 省略)
public class Label : WebControl
{
    // 
}


注意其中 // here 标注的地方。这些就是方法调用跳转的地方。

从以上的跟踪我们可以得到一个结论:
只有需要处理回发(PostBack) 的控件才必须放在 Form 内。
这种控件通常要实现 IPostBackEventHandler 或者 IPostBackDataHandler 接口。


而上面代码里的 Page.VerifyRenderingInServerForm(this) 方法正是我们做的试验里异常的抛出者。这个方法检测当前控件是否在一个 runat="server" 的 form 内部,并且在 Render 调用中。如果不是,则抛出异常。
我们看到上面的 Label 类中就保留了基类对 AddAttributesToRender 的默认实现,而没有加入对 Page.VerifyRenderingInServerForm(this)  这个检验的调用机制。

对控件开发者而言,如果你的控件需要处理回发事件或回发数据,则必须实现 IPostBackEventHandler 或 IPostBackDataHandler 接口。并且为了保险起见,应该重写 AddAttributesToRender 虚拟方法的实现,在其中调用 Page.VerifyRenderingInServerForm(this) 这个检验。

 

 

服务器控件与非html控件区别?

1.无form的页面也可以用,而且用得还很爽。
但不要在页面里放“需要回发的服务端控件”,如asp:TextBox,asp:Button,asp:LinkButton,asp:ImageButton,asp:DropDownList,asp:ListBox,asp:CheckBox,asp:CheckBoxList,asp:RadioButton,asp:RadioButtonList,asp:HiddenField,asp:FileUpload,asp:GridView,asp:DetailsView,asp:FormView……(生成Input标签的东东和其他与之有关的);
可以放:asp:Repeater,asp:Label,asp:HyperLink,asp:Image,asp:Table,asp:Literal,asp:Panel……

2.

a.实现了Page.VerifyRenderingInServerForm(this)方法的服务器控件必须放在form中,否则可以不放入form中

b.非服务器控件如果想回传数据,并且让服务器识别就必须加runat="server",而且要有name(不识别id)

 

Viewstate的理解?

大家来看我对ViewState的理解对不啊?我搞不清楚啊,请大家多多指教

1. 客户端向一个含有 <form runat="server">的页面发出一个GET请求,服务器端接收到该请求,会向
客户端返回一个 <input type='hidden' name="__VIEWSTATE />的隐藏域,由于此时是第一次请求,
所以这个ViewState为空。
2.用户填写好了表单并单击提交后(第一次post),服务器端会同时接收到提交上来的表单数据和ViewState
,但是此时ViewState也是空的。
3.服务器端接着会以我们编的代码逻辑去处理提交上来的表单数据,经过处理后的页面HTML又会发送给客户
端,但在把页面HTML发送给客户端之前,会先把处理后的数据保存在ViewState当中,然后这个ViewState
会随着HTML一起被发往客户端,此时ViewState中就有数据了,
4.客户端又接收到服务器发回的HTML和ViewState后,就会把页面展示到我们面前
5.加入我们此时又修改了表单的数据,那么又会产生一次回发(第二次post),那么服务器端会接收到回发
的表单数据和ViewState,不过这时的ViewState已经有值了
6.但是这时的表单数据和ViewState数据是有区别的。表单数据是最新的数据,反映了客户端最新填入的
信息,但是ViewState还是用户修改表单之前的那些旧数据。
7.那么,在服务器端怎么去恢复控件的状态呢?比如恢复TextBox的 Text 属性,我们是用表单数据去恢复,
还是利用ViewState去恢复了?如果利用ViewState去恢复,那恢复到的数据不是旧数据吗?
8.那么我的理解是:ViewState去恢复某些客户端不可编辑的属性,比如控件颜色,大小等;而表单数据去
恢复某些诸如Text这些客户端可修改的属性。
9.那么,假如我在服务器端有行代码TextBox1.Text,此时的这个Text应该是从表单数据那儿获取的吧?
Textbox1.Width应该是从ViewState获取的吧?

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值