ASP.NET 自定义表达式

当我们以 <%=DateTime.Now.ToString() %>(<%%>)在页面里呈现数据时,它到底是如何工作的呢?

据我发现,当页面里面包含<%%>符号时,页面在解析 编译期间 将在__BuildControlform1()函数里自动生成调用SetRenderMethodDelegate()方法( __ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));):如下:

[DebuggerNonUserCode]

private HtmlForm __BuildControlform1()

{

HtmlForm __ctrl = new HtmlForm();

base.form1 = __ctrl;

__ctrl.ID = "form1";

Literal __ctrl1 = this.__BuildControlLiteral1();

IParserAccessor __parser = __ctrl;

__parser.AddParsedSubObject(__ctrl1);

__ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Renderform1));

return __ctrl;

}

private void __Renderform1(HtmlTextWriter __w, Control parameterContainer)

{

__w.Write("\r\n ");

__w.Write(DateTime.Now.ToString());

__w.Write("\r\n <div>\r\n ");

parameterContainer.Controls[0].RenderControl(__w);

__w.Write("\r\n </div>\r\n ");

}

从上面代码我们可以发现,页面所有<%%>单独出现的都由一个Literal控件来呈现。并在BuildControlForm1里自动添加Literal控件并调用SetRenderMethodDelegate().

但是当我们

<asp:TextBox runat="server" Text=<%=DateTime.Now.ToString() %>></asp:TextBox>

为什么会编译出错呢?那是因为基于SetRenderMethodDelegate()方法是服务生成页面的Body部分(The model based on SetRenderMethodDelegate works for building the body of the page at render time, not for setting object properties at parse time).

那么怎么以声明的方式 控件属性?数据绑定表达式:

<asp:TextBox runat="server" Text="<%#DateTime.Now.ToString() %>"></asp:TextBox>

[DebuggerNonUserCode]

private TextBox __BuildControlTextBox1()

{

TextBox __ctrl = new TextBox();

base.TextBox1 = __ctrl;

__ctrl.ApplyStyleSheetSkin(this);

__ctrl.ID = "TextBox1";

__ctrl.DataBinding += new EventHandler(this.__DataBindingTextBox1);

return __ctrl;

}

public void __DataBindingTextBox1(object sender, EventArgs e)

{

TextBox dataBindingExpressionBuilderTarget = (TextBox) sender;

Page Container = (Page) dataBindingExpressionBuilderTarget.BindingContainer;

dataBindingExpressionBuilderTarget.Text = Convert.ToString(DateTime.Now.ToString(), CultureInfo.CurrentCulture);

}

由此我们发现代码自动注册了TextBox的DataBind事件。

数据表达式只有在DataBind方法被调用时才有效。所以我们要上面的代码呈现出我们希望的结果,我们需要在Page_Load中手动调用DataBind(). DataBind方法能被页面或特定的控件来触发。

但是在数据绑定表达式(#)外,还有一种表达式($)dynamic expression. 为什么要有另外一种表达式呢?先看看:

<asp:SqlDataSource runat="server"

ConnectionString='<%#System.Web.Configuration.WebConfigurationManager.ConnectionStrings["MyMemberShipConnstr"] %>'

SelectCommand="select * from aspnet_roles"></asp:SqlDataSource>

<asp:GridView runat="server" DataSource>

</asp:GridView>

上面的代码照常执行,当我们在Page_load中调用了DataBind()方法时. 但是当我们将SqlDataSource控件和GridView调换位置时,异常就会抛出:The ConnectionString property has not been initialized. 那是因为在GridView进行数据绑定时 数据库连接字符串还没有初始化。