当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > ASP.NET WebForm页面内容输出方式

ASP.NET
C# Quoted-Printable编码、解码
asp.net Google的translate工具翻译 API
.NET读取所有目录下文件正则匹配文本电子邮件
asp.net 半角全角转化工具
AjaxControlToolKit 显示浏览者本地语言的方法
asp.net HTML文件上传标签
ASP.NET 绑定DataSet中的多个表
ASP.NET 重定向的几种方法小结
Asp.Net 重定向必须要知道的一些资料
ASP.NET 导出到Excel时保留换行的代码
Asp.Net Cache缓存使用代码
document.getElementsByName和document.getElementById 在IE与FF中不同实现
GridView单元格合并
asp.net 大文件上传控件
asp.net 日期函数 某月的第一天和最后一天的日期
asp.net 时间类 一周的周一和周末的日期
C# javaScript函数的相互调用
asp.net membership 密码重设
"虚拟路径"..."映射到另一个应用程序,这是不允许的!
如何传值在2个页面之间 要求不刷新父页面,并且不能用Querystring传值

ASP.NET WebForm页面内容输出方式


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 247 ::
收藏到网摘: n/a

这次我们谈的话题是“Web Form页面上输出内容的方式”。这其实是一个非常旧的话题了,因为本文的内容甚至可以运用于ASP.NET 1.1之上。不过这个话题的适用范围很广,因为即使是目前最新的ASP.NET MVC框架,它的默认视图引擎依旧是基于ASP.NET WebForm的(如Page,Control,MasterPage)。甚至说,由于ASP.NET MVC框架的特性,我们会遇到更多在页面上“直接输出”内容的情况。因此,这个话题在ASP.NET MVC应用中可能由为重要。

那么就拿ASP.NET MVC举例吧。假如,我们在页面上生成一个Partial View,我们可以这么做:

<% Html.RenderPartial("MyPartialView"); %> 

然而,在前一篇文章中我们提出了一个新的方法Partial,它返回一个字符串,它可以在页面上这样使用:

<%= Html.Partial("MyPartialView") %>

一个aspx页面会被编译成Page类的一个子类,这个子类的主要“功能”是覆盖了基类的Render方法:

public class MyPage : Page
{
    protected override void Render(HtmlTextWriter writer)
    {
        ...
    }
} 
 
我们平时在aspx页面中编写的大量内容,其实都会变成操作writer的代码。例如使用writer.Write方法输出内容,或者把writer交给子控件的Render方法用于生成内容。那么,以上两种页面上的标记分别又是如何操作writer的呢?

<%= expression %>

首先是<%= %>标记。<%= %>标记内包含的是一个“表达式”,因此它不能以分号结尾。表达式内部的数据就会直接写入writer。例如这样的标记:

<%= DateTime.Now %>

在编译过后就成为:

writer.Write(DateTime.Now)

与<%= %>标记不同,<% %>标记中间其实包含的是“语句”。语句自然可以有多行,自然每行最后需要有分号,这就像我们平时写C#代码那样。不过实际上,语句的功能其实并不是为了“输出内容”,而是用来“控制逻辑”。例如,您在页面上写了这样的代码:

<% Func<int, bool> odd = i => i % 2 != 0; %>

这样就相当于您在Render方法内部声明了一个局部变量odd,它的类型是一个Func<int, bool>委托。而如果您编写这样的代码:

<% for (int i = 0; i < 10; i++) { %>
    <span>
        <%= i + 1 %>
    </span>
<% } %>

则生成的Render方法中就会包含:

for (int i = 0; i < 10; i++)
{
    writer.Write("<span>");
    writer.Write(i + 1);
    writer.Write("</span>");
}

如果是写在页面上的普通HTML标记,编译后就被当作普通字符串来处理了。有些朋友一直谈“客户端控件”等等,其实如果一个元素上没有runat="server"标记,ASP.NET只是把它们当作普通字符串处理,并不会有任何“HTML元素”的概念。当然,上面的代码表现的是“意图”,事实上在编译过后aspx页面中的空格和换行等字符也会包含在输出的内容中。

那么,既然<% %>中包含的是用来控制逻辑的语句,本身不是用来表示输出的,那么为什么刚才代码中的Html.RenderPartial方法也会生成页面内容呢?那是因为RenderPartial方法直接向当前HttpContext.Response.Output里写入字符了。很多朋友经常使用Response.Write来输出内容,其实在Write方法内部就是输出到Output中。

事实上,即使我们的页面中使用了HtmlTextWriter来输出内容,但它内部也是封装了Output所暴露出的TextWriter中。为了验证,您可以在代码中设置断点并观察Render方法的writer参数,在“正常情况下”可以发现writer.InnerWriter属性是一个HttpWriter对象,这是个TextWriter的子类,也是ASP.NET中定义的内部类型。

这便是ASP.NET页面输出的细节。那么请问,以下两种输出方式的区别是什么呢?

<%= "Hello World" %>
<% Response.Write("Hello World") %>

从效果上看,两者没有任何区别。但是实际上前者是使用页面的HtmlTextWriter对象输出的,而后者则直接向Response.Output里输出内容。这个区别看似不重要,但其实它会涉及到我们很多开发过程中可用的实践方式。在今后的文章中,我会提出生成页面内容的一些准则,解释这些准则的原因,并指出ASP.NET MVC本身是如何破坏这些设计准则的。

自然,修改版本的ASP.NET MVC会发布在MvcPatch项目中。

原文地址:http://www.cnblogs.com/JeffreyZhao/archive/2009/09/16/where-does-aspnet-page-render-to.html