AspxToHtml
UrlMapping
HtmlPage
/// <summary>
/// 路径映射
/// </summary>
public static class UrlMapping
{
/// <summary>
/// Aspx 转换到 Html
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string AspxToHtml(string url)
{
//判断路径是否为空
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("路径不能为空");
}
//分割路径
string[] temp = url.Split('?');
if (temp.Length != 1 && temp.Length != 2)
{
throw new ArgumentException(String.Format("路径 {0} 及其参数错误", url));
}
//获取路径后缀
string ext = Path.GetExtension(temp[0]);
if (!(ext.Equals(".aspx", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(String.Format("路径 {0} 类型必须为ASPX", url));
}
//截取.aspx中前面的内容
int offset = temp[0].LastIndexOf('.');
string resource = temp[0].Substring(0, offset);
//路径不带参数时
if (temp.Length == 1 || string.IsNullOrEmpty(temp[1]))
{
return string.Format("{0}.html", resource); //拼接
}
//路径带参数时
return string.Format("{0}___{1}.html", resource, temp[1]); //拼接
}
/// <summary>
/// Html 转换到 Aspx
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string HtmlToAspx(string url)
{
//判断路径是否为空
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("路径不能为空");
}
string ext = Path.GetExtension(url);
if (!(ext.Equals(".html", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(String.Format("路径 {0} 类型必须为HTML", url));
}
string[] temp = url.Split(new String[] { "___", "." }, StringSplitOptions.RemoveEmptyEntries);
if (temp.Length == 2)
{
return string.Format("{0}.aspx", temp[0]);
}
if (temp.Length == 3)
{
return String.Format("{0}.aspx?{1}", temp[0], temp[1]);
}
throw new ArgumentException(String.Format("资源 {0} 及其参数错误", url));
}
}
/// <summary>
/// 哪个页面想静态化,就继承这个类
/// </summary>
public class HtmlPage : Page
{
// <summary>
/// 获取物理路径,判断文件夹中有没有存在这个文件
/// 不存在的话,就会调用FilterStream类进行创建,并写入内容
/// 存在的话,就直接显示页面
/// </summary>
public override void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string htmlPage = UrlMapping.AspxToHtml(request.RawUrl);
string htmlFile = context.Server.MapPath(htmlPage);
if (File.Exists(htmlFile))
{
response.Redirect(htmlPage);
}
else
{
// Html 页面不存在
response.Filter = new FilterStream(response.Filter, htmlFile);
base.ProcessRequest(context);
}
}
}
/// <summary>
/// 后缀为HTML的,都经这里处理
/// Web.Config
/// <remove verb="*" path="*.HTML"/>
/// <add verb="*" path="*.HTML" type="HtmlHandler"/>
/// </summary>
public class HtmlHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
/// <summary>
/// 获取物理路径,判断文件夹中有没有存在这个文件
/// 不存在的话,就会调用FilterStream类进行创建,并写入内容
/// 存在的话,就直接显示页面
/// </summary>
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string htmlPage = request.RawUrl;
string htmlFile = context.Server.MapPath(htmlPage);
if (File.Exists(htmlFile))
{
response.WriteFile(htmlFile);
}
else
{
//Html 文件不存在
string aspxPage = UrlMapping.HtmlToAspx(htmlPage);
response.Redirect(aspxPage);
}
}
}
/// <summary>
/// 静态网页保存
/// </summary>
public class FilterStream : Stream
{
private Stream respStream, fileStream;
public FilterStream(Stream respStream, string filePath)
{
if (respStream == null)
{
throw new ArgumentNullException("输出流不能为空");
}
this.respStream = respStream;
try
{
this.fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write); //写入到文件夹中
}
catch
{
}
}
public override bool CanRead
{
get { return this.respStream.CanRead; }
}
public override bool CanSeek
{
get { return this.respStream.CanSeek; }
}
public override bool CanWrite
{
get { return this.respStream.CanWrite; }
}
public override void Flush()
{
this.respStream.Flush();
if (this.fileStream != null)
{
this.fileStream.Flush();
}
}
public override long Length
{
get { return this.respStream.Length; }
}
public override long Position
{
get
{
return this.respStream.Position;
}
set
{
this.respStream.Position = value;
if (this.fileStream != null)
{
this.fileStream.Position = value;
}
}
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.respStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
if (this.fileStream != null)
{
this.fileStream.Seek(offset, origin);
}
return this.respStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
this.respStream.SetLength(value);
if (this.fileStream != null)
{
this.fileStream.SetLength(value);
}
}
public override void Write(byte[] buffer, int offset, int count)
{
this.respStream.Write(buffer, offset, count);
if (this.fileStream != null)
{
this.fileStream.Write(buffer, offset, count);
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.respStream.Dispose();
if (this.fileStream != null)
{
this.fileStream.Dispose();
}
}
}
public class HtmlPanel : Control
{
private bool _isHtml = true;
private bool _includeSubControls = true;
/// <summary>
/// 获取或设置一个bool值,指示是否允许静态化。
/// </summary>
public bool IsHtml
{
get
{
return _isHtml;
}
set
{
_isHtml = value;
}
}
/// <summary>
/// 获取或设置一个bool值,指示静态化时是否包含子控件。
/// </summary>
public bool IncludeSubControls
{
get
{
return _includeSubControls;
}
set
{
_includeSubControls = value;
}
}
protected override void OnPreRender(EventArgs e)
{
if (IsHtml)
{
ParseLink();
}
base.OnPreRender(e);
}
/// <summary>
/// 执行超链接aspx到html的转变,可被子类重写。
/// </summary>
protected virtual void ParseLink()
{
Parse(this);
}
private void Parse(Control ctr)
{
ControlCollection children = ctr.Controls;
foreach (Control item in children)
{
if (item is HyperLink)
{
HyperLink link = (HyperLink)item;
link.NavigateUrl = UrlMapping.AspxToHtml(base.ResolveClientUrl(link.NavigateUrl));
}
else if (item is HtmlAnchor)
{
HtmlAnchor link = (HtmlAnchor)item;
link.HRef = UrlMapping.AspxToHtml(base.ResolveClientUrl(link.HRef));
}
else
{
if (IncludeSubControls && item.Controls.Count > 0)
{
Parse(item);
}
}
}
}
}