简述ASP.NET 2.0生成HTML的三种方法

Asp.net 专栏收录该内容
56 篇文章 0 订阅
 

由数据库驱动的动态WEB页面把我们编程人员从烦琐的查找替换中解放了出来,但如何事都有利弊,减少了我们的工作,但加重了服务器的负担,所以,各种各样的静态页面生成方法也就孕育而出了。本文只是简单叙述和总结了一下我所知道的几种ASP.NET静态页面生成技术,如有不妥之处还请大家包含和指教。

一、WebRequest

我们先来看一下MSDN对System.Net.WebRequest的解释吧。

WebRequest 是 .NET Framework 的请求/响应模型的 abstract 基类,用于访问 Internet 数据。使用该请求/响应模型的应用程序可以用协议不可知的方式从 Internet 请求数据,在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节。

请求从应用程序发送到某个特定的 URI,如服务器上的网页。URI 从一个为应用程序注册的 WebRequest 子代列表中确定要创建的适当子类。注册 WebRequest 子代通常是为了处理某个特定的协议(如 HTTP 或 FTP),但是也可以注册它以处理对特定服务器或服务器上的路径的请求。

如果在访问 Internet 资源时发生错误,则 WebRequest 类将引发 WebException。WebException.Status 属性是 WebExceptionStatus 值之一,它指示错误源。当 WebException.Status 为 WebExceptionStatus.ProtocolError 时,Response 属性包含从 Internet 资源接收的 WebResponse。

因为 WebRequest 类是一个 abstract 类,所以 WebRequest 实例在运行时的实际行为由 System.Net.WebRequest.Create 方法所返回的子类确定。有关默认值和异常的更多信息,请参见有关子类的文档,如 HttpWebRequest 和 FileWebRequest。

当我们传入的是 http://https://,则 Create 返回 HttpWebRequest 对象;如果是 file://,则 Create 方法返回 FileWebRequest 对象。.NET Framework 包括了 http://https://file:// URI 方案的支持。用 RegisterPrefix 方法注册要处理其他请求的自定义 WebRequest 子类。

在了解了WebRequest类之后,剩下来的就简单了,看下面代码:

//请求一个URL
System.Net.WebRequest request = System.Net.WebRequest.Create(url);
//返回该请求
WebResponse response = request.GetResponse();
//将得到的内容放入StreamReader中
StreamReader sr = new StreamReader(response.GetResponseStream());

StreamWriter sw = new StreamWriter(path, false, System.Text.Encoding.Default);
//写入到文件
sw.Write(sr.ReadToEnd());
sw.Close();
sr.Close();

特点:因为URL是我们自己传入的,所以就可以抓取到任何程序、任何网站的页面。可以制作成一个总的后台页面或Win form程序来进行批量生成HTML或小偷程序。

二、Response.Filter

老样子,还是来看一下MSDN上的解释。

Response.Filter:获取或设置一个包装筛选器对象,该对象用于在传输之前修改 HTTP 实体主体。当创建 Stream 对象并将 Filter 属性设置为 Stream 对象时,所有由 Write 发送的 HTTP 输出将通过筛选器。

顾名思义Filter是个筛选器,能让我们在代码输出之前做一些额外的操作。首先我们需要自定义一个继承Stream的类,代码如下:

public class ResponseFilter : Stream
{
    private Stream m_sink;
    private long m_position;
    private FileStream fs;

    public ResponseFilter(Stream sink, string filePath)
    {
        m_sink = sink;
        //创建一个文件流
        fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        //把内容输出到browser
        m_sink.Write(buffer, 0, count);
        //把内容输出到文件
        fs.Write(buffer, 0, count);
    }

    //重写抽象方法
    public override bool CanRead { get { return true; } }
    public override bool CanSeek { get { return false; } }
    public override bool CanWrite { get { return false; } }
    public override long Length { get { return 0; } }
    public override long Position { get { return m_position; } set { m_position = value; } }
    public override long Seek(long offset, System.IO.SeekOrigin direction) { return 0; }
    public override void SetLength(long length) { m_sink.SetLength(length); }
    //别忘了fs.Close()
    public override void Close() { m_sink.Close(); fs.Close(); }
    public override void Flush() { m_sink.Flush(); }
    public override int Read(byte[] buffer, int offset, int count) { return m_sink.Read(buffer, offset, count); }
}

然后我们就可以在需要生成HTML的页面中加入这个Filter就可以了。

//注意,要传入Response.Filter才能得要生成的HTML流
Response.Filter = new ResponseFilter(Response.Filter, path);

特点:可以在页面第一个浏览时才生成HTML,做到按需生成,效率上比较好。如果大面积的页面需要加载这个Filter,那我们可以使用IHttpHandlerFactory或IHttpModule。

三、Page.Render

这个方法也是比较简单的,我们重写Page的Render方法,以达到保存HTML的目的。代码如下:

protected override void Render(HtmlTextWriter writer)
{
    //这是默认的Render实现,直接输出到writer中
    //base.Render(writer);

    StringWriter html = new StringWriter();
    HtmlTextWriter tw = new HtmlTextWriter(html);
    //通过base.Render()方法,把生成的HTML写入到我们定义的tw中
    base.Render(tw);

    string path = Server.MapPath("~/html/Render_" + Guid.NewGuid() + ".html");
    StreamWriter sw = new StreamWriter(path, false, System.Text.Encoding.Default);
    //写入到文件中
    sw.Write(html.ToString());
    sw.Close();
    //写入到writer中,以输出页面的HTML
    //注意,这里不能再调用base.Render(writer),会出现错误
    writer.Write(html.ToString());
}

特点:比较繁琐。:-(

四、小结

综上所述,在ASP.NET中生成HTML还是简单和方便的,推荐大家使用第一种和第二种。对于自定义模板再做文本替换的方法,在ASP中使用的比较多,但是也比较麻烦,所以在此也就不再讨论了。

本文只是展示了一些生成HTML的基本方法,并没有涉及到具体使用中的各种生成策略、URL重写方案等等,在以后的文章中再做讨论。

有待解决的疑点

  • 浏览生成的HTML页面时,ViewState如何处理(丢掉还是……)
  • 页面PostBack如何处理(不PostBack还是……)

参考资料:

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值