原文地址:
Godaddy的虚拟主机支持多个域名,但是我再配置BlogEngine.NET的时候,发现生成的URL包含虚拟目录,如:http://mydomain/blog/...... 红色的blog就是我再主机上面建立的子目录,用于存放BlogEngine.NET的目录。如何不让blog显示在生成的URL中呢?
如果修改源代码,那么以后的升级会很麻烦。所以解决方法必须要做到可配置,对源代码修改最小化。我的思路是添加一个HttpModule,在 HttpModule中将所有的a标签里面包含虚拟目录名称的替换成空字符串。这样对源代码的修改只是在web.config里面多注册一个 HttpModule。
方法确定了,有个关键问题需要解决:如何在HttpModule中修改Http输出内容?方法就是使用HttpApplication.Response.Filter,自定义一个Filter,在Filter里面实现URL的分析和处理。
关键代码:
1.定义HttpModule
public class VitualPathHttpModule:IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState); } void context_ReleaseRequestState( object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; // 装配过滤器 application.Response.Filter = new VirtualPathFilter(application.Response.Filter, application); } }
2.定义自定义Filter:VirtualPathFilter
public class VirtualPathFilter : Stream { Stream responseStream; long position; HttpApplication context; private VirtualPathFilter() { } public VirtualPathFilter(Stream inputStream,HttpApplication inputContext) { responseStream = inputStream; context = inputContext; } #region Write public override void Write( byte [] buffer, int offset, int count) { string strContent = UTF8Encoding.UTF8.GetString(buffer); string vitualPath = VirtualPathUtility.ToAbsolute(ConfigurationManager.AppSettings[ " BlogEngine.VirtualPath " ]); if ( ! string .IsNullOrEmpty(vitualPath)) { var vitualPath1 = vitualPath.TrimStart( ' / ' ); var vitualPath2 = vitualPath.TrimEnd( ' / ' ); var vitualPath3 = vitualPath.Trim( ' / ' ); string pattern = " <a[^<>]+href=\"[^>\"]* " + vitualPath3 + " [^>\"]*\" " ; Regex reg = new Regex(pattern, RegexOptions.IgnoreCase); var ms = reg.Matches(strContent); List < string > values = new List < string > (); foreach (Match item in ms) { var value = item.Value; if (values.Contains(value)) { continue ; } values.Add(value); if (value.IndexOf(vitualPath) > - 1 ) { value = value.Replace(vitualPath, " / " ); } if (value.IndexOf(vitualPath1) > - 1 ) { // othersite/blog/#NET -> #NET value = value.Replace(vitualPath1, "" ); } if (value.IndexOf(vitualPath2) > - 1 ) { // /othersite/blog -> / value = value.Replace(vitualPath2, " / " ); } if (value.IndexOf(vitualPath3) > - 1 ) { value = value.Replace(vitualPath3, "" ); } strContent = strContent.Replace(item.Value, value); } } responseStream.Write(UTF8Encoding.UTF8.GetBytes(strContent), offset, UTF8Encoding.UTF8.GetByteCount(strContent)); } #endregion #region Filter Overrides public override bool CanRead { get { return true ; } } public override bool CanSeek { get { return true ; } } public override bool CanWrite { get { return true ; } } public override void Close() { responseStream.Close(); } public override void Flush() { responseStream.Flush(); } public override long Length { get { return 0 ; } } public override long Position { get { return position; } set { position = value; } } public override int Read( byte [] buffer, int offset, int count) { return responseStream.Read(buffer, offset, count); } public override long Seek( long offset, SeekOrigin origin) { return responseStream.Seek(offset, origin); } public override void SetLength( long length) { responseStream.SetLength(length); } #endregion }
3.在Web.config中注册HttpModule
< modules > < add name ="WwwSubDomainModule" type ="BlogEngine.Core.Web.HttpModules.WwwSubDomainModule, BlogEngine.Core" /> < add name ="UrlRewrite" type ="BlogEngine.Core.Web.HttpModules.UrlRewrite, BlogEngine.Core" /> < add name ="CompressionModule" type ="BlogEngine.Core.Web.HttpModules.CompressionModule, BlogEngine.Core" /> < add name ="ReferrerModule" type ="BlogEngine.Core.Web.HttpModules.ReferrerModule, BlogEngine.Core" /> < add name ="VitualPathModule" type ="BE.Extention.VitualPathHttpModule,BE.Extention" /> </ modules >
至此,BlogEngine.NET生成的URL里面就不包含虚拟目录了,大功告成。