原文地址:http://hongzhang.me/post/2011/06/11/godaddy-blogengine-virtualpath.aspx     

      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里面就不包含虚拟目录了,大功告成。


posted on 2011-06-18 21:13  试翼阁  阅读(365)  评论(0)    收藏  举报