我这里是用HttpHandlerFactory和在Web.config中添加一个配置节来实现重写的,举个例子先:
原始Url:abc.aspx?aid=121&bid=321&mid=9
重写Url:abc-121-321-9.shtml
原始Url:xyz.aspx?type=a 或者xyz.aspx?type=b
重写Url:xyz-a.shtml或者xyz-b.shtml
而且这里希望一劳永逸的实现Url参数类型千变万化的形式的重写。
先看我们需要什么样的配置:
对于每一种重写我们都需要写出要重写成的Url的正则表达式的匹配形式,然后我们还需要配置原始Url的aspx路径,再就需要配置每一个参数在重写成的Url中怎么提取出来成为查询字符串,让原始的aspx去读取,说到这里,请看下面具体的配置节。
 <configSections>
<configSections> <section name="handlerSettings" type="book.Provider.ConfigHandler, book"/>
    <section name="handlerSettings" type="book.Provider.ConfigHandler, book"/> </configSections>
  </configSections> 
     <!--配置Url路径重写参数,如有任何疑问联系赵玉开-->
  <!--配置Url路径重写参数,如有任何疑问联系赵玉开--> <handlerSettings>
  <handlerSettings>     <!--
  <!-- 一个handler代表一中url的映射
  一个handler代表一中url的映射 regex是用来匹配Url的,如果匹配就使用对应的aspxPath中映射的handler
  regex是用来匹配Url的,如果匹配就使用对应的aspxPath中映射的handler aspxPath需要是一个可以经过Server.MapPath转换的aspx文件的虚拟路径
  aspxPath需要是一个可以经过Server.MapPath转换的aspx文件的虚拟路径 params是在url中包含参数的设置
  params是在url中包含参数的设置 param的两个属性:name是连接字符串的名字,valueRegexGroupName是正则表达式中匹配的对应名字的查询字符串的值的正则表达式组名字
  param的两个属性:name是连接字符串的名字,valueRegexGroupName是正则表达式中匹配的对应名字的查询字符串的值的正则表达式组名字 -->
  --> <handler name="news">
    <handler name="news"> <regex>/(?<id>[\d]+).shtml</regex>
        <regex>/(?<id>[\d]+).shtml</regex> <aspxPath>detail.aspx</aspxPath>
        <aspxPath>detail.aspx</aspxPath> <params>
        <params> <param name="id" valueRegexGroupName="id"/>
            <param name="id" valueRegexGroupName="id"/> </params>
        </params> </handler>
    </handler>         </handlerSettings>
  </handlerSettings>请大家看配置里面的注释。
有了配置节,我们就需要解析配置的类了,如下ConfigHandler用来读取配置节的信息,并将所有的配置信息实例化成ConfigItem 数组,然后放在这个类的一个静态数组中。


 public class ConfigHandler:System.Configuration.IConfigurationSectionHandler
public class ConfigHandler:System.Configuration.IConfigurationSectionHandler
 
     {
{ protected ConfigHandler()
        protected ConfigHandler()
 
         {
{ 
             }
        }
 static private ConfigItem[] _handlerConfigArray;
        static private ConfigItem[] _handlerConfigArray; [System.Xml.Serialization.XmlArrayItem("handler",typeof(ConfigItem))]
        [System.Xml.Serialization.XmlArrayItem("handler",typeof(ConfigItem))] static public ConfigItem[] HandlerConfigArray
        static public ConfigItem[] HandlerConfigArray
 
         {
{
 get
            get {return _handlerConfigArray;}
{return _handlerConfigArray;} }
        }

 IConfigurationSectionHandler 成员#region IConfigurationSectionHandler 成员
        IConfigurationSectionHandler 成员#region IConfigurationSectionHandler 成员
 public object Create(object parent, object configContext, System.Xml.XmlNode section)
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
 
         {
{ XmlNodeList nodeList = section.SelectNodes("handler");
            XmlNodeList nodeList = section.SelectNodes("handler"); ArrayList configList = new ArrayList();
            ArrayList configList = new ArrayList(); foreach(XmlNode node in nodeList)
            foreach(XmlNode node in nodeList)
 
             {
{ ConfigItem item = new ConfigItem();
                ConfigItem item = new ConfigItem(); item.Name = node.Attributes["name"].Value;
                item.Name = node.Attributes["name"].Value; 
                 XmlNode regexNode = node.SelectSingleNode("regex");
                XmlNode regexNode = node.SelectSingleNode("regex");  item.GlobalRegex = regexNode.InnerText;
                item.GlobalRegex = regexNode.InnerText;
 XmlNode aspxNode = node.SelectSingleNode("aspxPath");
                XmlNode aspxNode = node.SelectSingleNode("aspxPath"); item.AspxPath = aspxNode.InnerText;
                item.AspxPath = aspxNode.InnerText;
 XmlNode paramsNode = node.SelectSingleNode("params");
                XmlNode paramsNode = node.SelectSingleNode("params"); if(paramsNode != null)
                if(paramsNode != null)
 
                 {
{ XmlNodeList paramNodeList = paramsNode.SelectNodes("param");
                    XmlNodeList paramNodeList = paramsNode.SelectNodes("param");
 ArrayList list = new ArrayList();
                    ArrayList list = new ArrayList(); foreach(XmlNode paramNode in paramNodeList)
                    foreach(XmlNode paramNode in paramNodeList)
 
                     {
{ ConfigParam p = new ConfigParam();
                        ConfigParam p = new ConfigParam(); p.Name = paramNode.Attributes["name"].Value;
                        p.Name = paramNode.Attributes["name"].Value; p.ValueRegexGroupName = paramNode.Attributes["valueRegexGroupName"].Value;
                        p.ValueRegexGroupName = paramNode.Attributes["valueRegexGroupName"].Value;
 list.Add(p);
                        list.Add(p); }
                    }
 item.Params = (ConfigParam[])list.ToArray(typeof(ConfigParam));
                    item.Params = (ConfigParam[])list.ToArray(typeof(ConfigParam)); }
                } configList.Add(item);
                configList.Add(item); }
            }
 _handlerConfigArray = (ConfigItem[])configList.ToArray(typeof(ConfigItem));
            _handlerConfigArray = (ConfigItem[])configList.ToArray(typeof(ConfigItem));
 
             return null;
            return null; }
        }
 #endregion
        #endregion }
    }
 public class ConfigItem
    public class ConfigItem
 
     {
{
 public ConfigItem()
        public ConfigItem() {}
{}
 private string _name;
        private string _name; public string Name
        public string Name
 
         {
{
 get
            get {return _name;}
{return _name;}
 set
            set {_name = value;}
{_name = value;} }
        }
 private string _globalRegex;
        private string _globalRegex;
 public string GlobalRegex
        public string GlobalRegex
 
         {
{
 get
            get {return _globalRegex;}
{return _globalRegex;}
 set
            set {_globalRegex = value;}
{_globalRegex = value;} }
        }
 public string _aspxPath;
        public string _aspxPath; public string AspxPath
        public string AspxPath
 
         {
{
 get
            get {return _aspxPath;}
{return _aspxPath;}
 set
            set {_aspxPath = value;}
{_aspxPath = value;} }
        }
 private ConfigParam[] _params;
        private ConfigParam[] _params; public ConfigParam[] Params
        public ConfigParam[] Params
 
         {
{
 get
            get {return _params;}
{return _params;}
 set
            set {_params = value;}
{_params = value;} }
        } }
    }
 public class ConfigParam
    public class ConfigParam
 
     {
{ private string _name;
        private string _name;
 public string Name
        public string Name
 
         {
{
 get
            get {return _name;}
{return _name;}
 set
            set {_name = value;}
{_name = value;} }
        }
 private string _valueRegexGroupName;
        private string _valueRegexGroupName; 
         public string ValueRegexGroupName
        public string ValueRegexGroupName
 
         {
{
 get
            get {return _valueRegexGroupName;}
{return _valueRegexGroupName;}
 set
            set {_valueRegexGroupName = value;}
{_valueRegexGroupName = value;} }
        } }
    }
解析出了重写的配置信息,我们的主角就该出场了,从IHttpHandlerFactory 继承的HanderFactory类

 HandlerFactory
HandlerFactory public class HandlerFactory:IHttpHandlerFactory
public class HandlerFactory:IHttpHandlerFactory
 
     {
{ public HandlerFactory()
        public HandlerFactory()
 
         {
{ }
        }

 IHttpHandlerFactory 成员#region IHttpHandlerFactory 成员
        IHttpHandlerFactory 成员#region IHttpHandlerFactory 成员
 public void ReleaseHandler(IHttpHandler handler)
        public void ReleaseHandler(IHttpHandler handler)
 
         {
{ }
        }
 public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
 
         {
{ url = url.ToLower();
            url = url.ToLower();
 foreach(ConfigItem ci in ConfigHandler.HandlerConfigArray)
            foreach(ConfigItem ci in ConfigHandler.HandlerConfigArray)
 
             {
{ Regex regex = new Regex(ci.GlobalRegex,RegexOptions.IgnoreCase);
                Regex regex = new Regex(ci.GlobalRegex,RegexOptions.IgnoreCase); Match match = regex.Match(url);
                Match match = regex.Match(url); if(match.Success)
                if(match.Success)
 
                 {
{ string queryString = string.Empty;
                    string queryString = string.Empty;
 if(ci.Params != null)
                    if(ci.Params != null)
 foreach(ConfigParam cp in ci.Params)
                    foreach(ConfigParam cp in ci.Params) {
{ queryString += string.Format("{0}={1}&",cp.Name,match.Groups[cp.ValueRegexGroupName].Value);
                        queryString += string.Format("{0}={1}&",cp.Name,match.Groups[cp.ValueRegexGroupName].Value); }
                    }
 foreach(string queryKey in context.Request.QueryString.AllKeys)
                    foreach(string queryKey in context.Request.QueryString.AllKeys)
 
                     {
{ if(queryString.IndexOf("&" + queryKey + "=") == -1 && queryString.IndexOf(queryKey + "=") == -1)
                        if(queryString.IndexOf("&" + queryKey + "=") == -1 && queryString.IndexOf(queryKey + "=") == -1)
 
                         {
{ queryString += string.Format("{0}={1}&",queryKey,context.Request.QueryString[queryKey]);
                            queryString += string.Format("{0}={1}&",queryKey,context.Request.QueryString[queryKey]); }
                        } }
                    } 
                     queryString = queryString.TrimEnd('&');
                    queryString = queryString.TrimEnd('&');
 context.RewritePath(url,"",queryString);
                    context.RewritePath(url,"",queryString);
 return PageParser.GetCompiledPageInstance(url, context.Server.MapPath(ci.AspxPath), context);
                    return PageParser.GetCompiledPageInstance(url, context.Server.MapPath(ci.AspxPath), context); }
                }
 }
            }
 
             ErrorHandler.RedirectFor400();
            ErrorHandler.RedirectFor400();
 return null;
            return null; }
        }
 #endregion
        #endregion }
    }
我们只实现了接口的GetHandler方法首先我们需要逐个的用配置中的正则表达式去匹配传进来的Url,如果改配置项匹配了Url,那么就开始根据配置的参数项,提取url中的查询字符串的值,并组成一个查询字符串,需要注意的是查询字符串并不只是这一部分因为xxx.shtml还可能带有查询字符串的,所以我们还需要把这一部分的查询字符串附加到提取出来的查询字符串的后面,最后我们使用PageParser.GetCompiledPageInstance返回一个IHttpHandler的实例,到这儿基本上就结束了。
<handler name="book"> 
<regex>/book/(?<id>[\d]+).shtml</regex> 
<aspxPath>../book.aspx</aspxPath> 
<params> 
<param name="id" valueRegexGroupName="id"/> 
</params> 
</handler>  回复  更多评论
   
 
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号