Asp.Net中动态页面转静态页面

来源:互联网 发布:全国城市区号表 sql 编辑:程序博客网 时间:2024/05/16 10:08

由于搜索引擎对aspx页面收录和html页面收录率的差别以及页面资源占用问题,我们很多时候需要实现ASPX页面动态转静态。网上也有很多人  
   
  讨论其实现方法,本人实践后总结两种主流方法如下:  
   
  第一种方法:  
  使用模板转换,步骤如下:  
  1、建立MyConvert.cs类文件    
  using   System;    
  //记得添加以下三引用    
  using   System.Text;    
  using   System.Web;    
  using   System.IO;    
  namespace   TesConvert    
  {    
    ///   <summary>    
    ///   MyConvert   的摘要说明。    
    ///   </summary>    
    public   class   MyConvert    
    {    
      public   MyConvert()    
      {    
        //    
        //   TODO:   在此处添加构造函数逻辑    
        //    
      }    
      public   bool   WriteFile(string   strText,string   strContent,string   strAuthor)    
      {    
        string   path   =   HttpContext.Current.Server.MapPath("/TesConvert/news/");//定义html文件存放路径    
        Encoding   code   =   Encoding.GetEncoding("gb2312");//定义文字编码    
        //   读取模板文件    
        string   temp   =   HttpContext.Current.Server.MapPath("/TesConvert/text.html");    
        StreamReader   sr=null;    
        StreamWriter   sw=null;    
        string   str="";      
        try    
        {    
          sr   =   new   StreamReader(temp,   code);    
          str   =   sr.ReadToEnd();   //   读取文件    
        }    
        catch(Exception   exp)    
        {    
          HttpContext.Current.Response.Write(exp.Message);    
          HttpContext.Current.Response.End();    
          sr.Close();    
        }    
        string   htmlfilename=path   +   DateTime.Now.ToString("yyyyMMddHHmmss")+".html";    
        //   替换内容    
        //   这时,模板文件已经读入到名称为str的变量中了    
        str   =   str.Replace("ShowArticle",strText);   //模板页中的ShowArticle    
        str   =   str.Replace("title",strText);    
        str   =   str.Replace("content",strContent);    
        str   =   str.Replace("author",strAuthor);    
        //   写文件    
        try    
        {    
          sw   =   new   StreamWriter(htmlfilename,false,code);    
          sw.Write(str);    
          sw.Flush();    
        }    
        catch(Exception   ex)    
        {    
          HttpContext.Current.Response.Write(ex.Message);    
          HttpContext.Current.Response.End();    
        }    
        finally    
        {    
          sw.Close();    
        }    
        return   true;    
      }    
      }    
  }    
  2、TestNews.aspx文件:  
    添加三和TextBox分别为:tbx_Title、tbx_Content、tbx_Author和一个Button:btn_AddNews。    
  TestNews.aspx.cs文件    
  private   void   btn_AddNews_Click(object   sender,   System.EventArgs   e)    
      {    
        MyConvert   Hover   =   new   MyConvert();    
         
   
  if(Hover.WriteFile(this.txb_Title.Text.ToString(),Server.HtmlDecode(this.txb_Content.Value),this.txb_Author.Text.ToString()))    
        {    
          Response.Write("添加成功");    
        }    
        else    
        {    
          Response.Write("生成HTML出错!");    
        }    
      }    
  3、添加模板text.html文件      
  <head>ShowArticle</head>  
  <body>  
  title<br>  
  content<br>  
  author  
  </body>  
  说明:一.news文件夹必须赋予asp.net用户写入的权限。这是一个简单的实现例子,实际项目必须先将数据保存到数据库下面,在datagird中  
   
  调用数据库下面html文件的URL地址。二.默认情况下,我们是不能向TextBox、TextArea中添加html语法的,必须修改config文件,在  
   
  <system.web>下面添加<pages   validateRequest="false"   />,但是这样做的话,整个项目中都允许键入html标签了,暂时还不知道其他的方。    
  缺点:这种方法是在ASP.net在页面所有内容生成后、输出内容前对页面内容进行操作以前曾说过用HttpModule来在Response前更改,不够灵活  
   
  ,每行修改response,比较费力。  
   
  第二种方法:  
  重写AttributeCollection.Render,比较灵活(msdn如是说:“在呈现阶段,所有   ASP.NET   移动设备适配器都通过一个称为文本编写器的对象  
   
  来编写它们的输出。文本编写器对象是从   TextWriter   基类创建的。”)  
  可以写个基类,如:  
  public   class   BasePage:   System.Web.UI.Page  
  {  
      public   BasePage()  
      {  
      }  
      protected   override   void   Render(System.Web.UI.HtmlTextWriter   writer)  
      {  
          string   name=Request.Url.AbsolutePath.Substring(1,Request.Url.AbsolutePath.Length-1).Replace("aspx","htm");  
          string   newurl="";  
          if(name.IndexOf("/")>0)  
          {  
              newurl=Server.MapPath("../")   +   name;  
          }  
          else  
          {  
              newurl=Server.MapPath("./")   +   name;  
          }  
          MemoryStream   ms   =   new   MemoryStream();  
          StreamWriter   sww   =   new   StreamWriter(ms);  
          StreamWriter   swr   =   new   StreamWriter(newurl);  
          System.Web.UI.HtmlTextWriter   htmlw   =   new   HtmlTextWriter(swr);  
          base.Render(htmlw);  
          htmlw.Flush();  
          htmlw.Close();  
          string   strLL   =   System.Text.Encoding.UTF8.GetString(ms.ToArray());  
          Response.Write(strLL);  
          Response.Redirect(Request.Url.AbsoluteUri.Replace("aspx","htm"),   true);  
      }  
  }  
  然后在需要生成静态页面的页面中继承就可以了。  
   
  说明:这种办法是在Asp.net的生成动作完成之后,再进行一次转换。  
  缺点:觉得本质上应该还是属于频繁post的aspx页面。   
   
 下面是在网络上搜索到的代码:

关于在Asp.Net中动态页面转静态页面的方法网上比较多。结合实际的需求,我在网上找了一些源代码,并作修改。现在把修改后的代码以及说明写一下。

一下是一个页面转换的类,该类通过静态函数Changfile()来实现,动态页面到静态页面的转换。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;

/**//// <summary>
/// Summary description for HtmlProxy
/// </summary>
public class HtmlProxy
...{
    public HtmlProxy()
    ...{
    }
    public static bool ChangeFile(int id)
    ...{
        string filename = HttpContext.Current.Server.MapPath("Post_" + id + ".html");
        //尝试读取已有文件
        Stream st = GetFileStream(filename);
        //如果文件存在并且读取成功
        if (st != null)
        ...{
            using (st)
            ...{
                StreamToStream(st, HttpContext.Current.Response.OutputStream);
                return true;
                //Response.End();
            }
        }
        else
        ...{
            StringWriter sw = new StringWriter();
            HttpContext.Current.Server.Execute("ForumDetail.aspx?PID=" + id, sw);

            string content = sw.ToString();
            //写进文件
            try
            ...{
                using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Write))
                ...{
                    using (StreamWriter stw = new StreamWriter(fs, HttpContext.Current.Response.ContentEncoding))
                    ...{
                        stw.Write(content);
                    }
                }
                return true;
            }
            catch ...{ return false; }
        }
    }

    private static Stream GetFileStream(string filename)
    ...{
        try
        ...{
            DateTime dt = File.GetLastWriteTime(filename);
            TimeSpan ts = dt - DateTime.Now;
            if (ts.TotalHours > 1)
            ...{
                //一小时后过期
                return null;
            }
            return new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
        }
        catch ...{ return null; }
    }


    static public void StreamToStream(Stream src, Stream dst)
    ...{
        byte[] buf = new byte[4096];
        while (true)
        ...{
            int c = src.Read(buf, 0, buf.Length);
            if (c == 0)
                return;
            dst.Write(buf, 0, c);
        }
    }
}
 在页面文件中,ForURL.aspx的后台代码如下:

 

protected void Page_Load(object sender, EventArgs e)
    ...{
        try
        ...{
            int id = int.Parse(Request.QueryString["PID"]);
            if(HtmlProxy.ChangeFile(id))
            ...{
                  Response.Redirect("Post_" + id + ".html");
            }
            else
            ...{
                  Response.Redirect("Post.aspx?PID=" + id );
            }
        }
        catch ...{
         }
    }

 
原创粉丝点击