一完美的关于请求的目录不存在而需要url重写的解决方案!

本人认为此文章 只适合做做www.ruan56.com/test 或 http://blog.ruan56.com/test 的二级域名 其中:http://blog.ruan56.com 是已经开通的二级域名  以下代码,还需要修改才能实现如上功能,大概把思路讲一下

我只想要达到这样的目的,和博客园一样当用户注册后将给他个如:http://www.cnblogs.com/注册名 
一样的地址,以便用户能够通过此地址能够访问他的博客,而注册名这个目录其实是不存在的,本文也只解决这个问题. 
从我开始想到去解决这个问题到现在解决大约5天时间,期间我查阅了基本上所有我能够找的的资料,博客园的搜索引擎甚至被我搜烂了,我有好多不明白,我不知道博客写文章是干什么的?不知道你们写的代码自己测试了没?我也不知道你们的代码是不是抄袭别人的?我认为做为一名博客,如果你引用别人代码,希望自己能够先做点测试,如果是自己写的,我希望是先测试成功了再帖出来,以免误人子弟. 
同时我也在CSDN连发两帖,花了260大分,甚至有的朋友连意思都没有搞明白就回帖,当然也谢谢他们的热心,帖子地址是:http://community.csdn.net/Expert/topic/4406/4406615.xml?temp=.513714  还有个:http://community.csdn.net/Expert/topic/4401/4401936.xml?temp=.317898 
大家有兴趣可以看看. 
期间我碰到了两个主要问题: 
1,如果和博客园一样设置iis添加>*的隐射让所有的请求不经过iis而让aspnet_isapi.dll来处理,带来性能的损失不说,当我们运行http://localhost/RewriteTest的时候既然要我输入用户名和密码来登陆域,出现什么由于acl,访问被拒绝的401.3错误,我在iis设置权限,在RewriteTest目录添加了所有用户组的读写权限故障依然存在,其中RewriteTest是我的应用程序目录,本来我们访问这个地址是会自动转到这个目录下的default.aspx文件的,但是为什么出现这个错误呢?不知道博客园的代码是怎么实现这点的,博客园的代码左一个factory工厂右一个fctory工厂,我真想跳河啊,看不懂,所以不看他的. 


为什么说完美呢?其实我认为这解决方法不完美,因为他还要设置下iis,我渴望朋友们能够给我更完美的方法,所以冠之为完美,请见晾.并且我也认为这解决方法处理类似的问题应该最为简单高效.恳请大家能够给出更好的解决方法,我相信你在我心中将会和我师傅吴旗娃一样是我心中的神!感谢师傅!我所有的代码在iis5.1,xp sp2系统,vs.net2005下测试通过.我的思路是截获404错误,然后用一个实现IHttpHandler接口的类来处理这个错误路径.我的方法如下: 
一,先在vs.net2005先新建个web site站点,我命名为RewriteTest,然后添加个404.aspx文件. 
二,修改iis.在iis中找到站点RewriteTest,右击选属性,在弹出的对话面板里面选,再点里面的404,选编辑属性,文件类型选url,下面输入:/RewriteTest/404.aspx  好了,点确定到头.在这里为什么我们不在web.config里面用<customErrors>来配置路径呢?因为在web.config里面设置的如果输入的是一个不存在的文件他能够截获,如果输入的是一个不存在的目录他就不能够截获拉,所以只能够在iis里面设置. 
三,我们现在修改web.config文件,让路径404.aspx来让我们的一个实现了IHttpHandler接口的类来处理他,修改如下:<system.web> 
    <httpHandlers> 
      <add verb="*" type="RewriteTest.Http404" path="404.aspx"/> 
    </httpHandlers> 
其中RewriteTest是名字空间,Http404是一个实现了IHttpHandler接口的类, 这样当我们的404.aspx截获到错误的时候会由这个Http404类来处理]
四,我们添加个类Http404,代码如下,有详细的注释:
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;
namespace RewriteTest
{
    /// <summary>
    /// Summary description for Http404
    /// </summary>
    public class Http404:IHttpHandler
    {
        public Http404()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public void ProcessRequest(HttpContext context)
        {
            //throw new Exception("The method or operation is not implemented.");
            string errorPath = context.Request.RawUrl.ToLower();
            context.Response.Write(errorPath);
        }

        #endregion

        #region IHttpHandler Members

        bool IHttpHandler.IsReusable
        {
            get { return false; }
        }

        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            //首先我们取得请求的原始url,比如我们请求的是http://localhost/RewriteTest/123456
            //RewriteTest是这个应用程序的名字,返回的将是/rewritetest/404.aspx?404;http://localhost/rewritetest/123456
            //请大家注意404后面的;
            string errorString = context.Request.RawUrl.ToLower();
            //context.Response.Write(errorString);
            //再把得到的地址按照;分割下将得到结果是:http://localhost/rewritetest/123456
            //这个时候我们再想办法得到那个不存在的虚拟目录
            errorString = errorString.Split(';')[1];
            //也可以写成这样:errorString = errorString.Split(new char[]{';'})[1];
            //context.Response.Write(errorString);
            //如果url含有点.我们就判断他带有后缀如.gif.jpg.asp.......我们就输出请求资源不存在的错误信息
            if (errorString.IndexOf(".") < 0)
            {
                //去掉前面的http://
                errorString = errorString.Remove(0, 7);
                //context.Response.Write(errorString);
                //再得到域名
                string hostName = context.Request.Url.Host;
                errorString = errorString.Remove(0, hostName.Length);
                //context.Response.Write(errorString);
                //再得到请求的应用程序路径
                string appPath = context.Request.ApplicationPath;
                errorString = errorString.Remove(0, appPath.Length);
                //context.Response.Write(errorString);
                if (errorString.StartsWith("/"))
                {
                    //如果前面有/就去掉/
                    errorString = errorString.Remove(0, 1);
                }
                if (errorString.EndsWith("/"))
                {
                    //如果以/结尾我们也去掉他
                    errorString = errorString.Remove(errorString.Length - 1, 1);
                }
                if (errorString.IndexOf("/") < 0)
                {
                    //如果中间含有/我们就不理他
                    //好了,我们现在实现url重写,就是页面跳转,在这里我很奇怪为什么不能够用
                    //context.RewritePath来实现,而要用Server.Transfer
                    context.Server.Transfer("~/page.aspx?name=" + errorString);
                }
            }
            else
            {
                context.Response.Write("懒MM.你请求的资源不存在,请点<a href='default.aspx'>这里</a>返回首页!");
            }
        }

        #endregion
    }
}
五,我们再添加个page.aspx文件,后台就一句代码: protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(Request.QueryString["name"].ToString());
    }
我们也把前台的标题改下:<title>懒MM</title>
我们现在运行下,输入:http://localhost/RewriteTest/123456
123456这个目录不存在的,大家可以看到,这个时候地址栏里面的地址依然是http://localhost/RewriteTest/123456
但是标题变成了懒MM,内容也是page.aspx的 内容拉!

你可能感兴趣的:(一完美的关于请求的目录不存在而需要url重写的解决方案!)