Url重写一劳永逸篇

  Url 重写可以提升用户体验,所以我们一直在追求,呵呵,先来一句广告语。 

我这里是用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去读取,说到这里,请看下面具体的配置节。

None.gif < configSections >
None.gif    
< section  name ="handlerSettings"  type ="book.Provider.ConfigHandler, book" />
None.gif  
</ configSections >
None.gif    
None.gif  
<!-- 配置Url路径重写参数,如有任何疑问联系赵玉开 -->
None.gif  
< handlerSettings >     
None.gif  
<!--
None.gif  一个handler代表一中url的映射
None.gif  regex是用来匹配Url的,如果匹配就使用对应的aspxPath中映射的handler
None.gif  aspxPath需要是一个可以经过Server.MapPath转换的aspx文件的虚拟路径
None.gif  params是在url中包含参数的设置
None.gif  param的两个属性:name是连接字符串的名字,valueRegexGroupName是正则表达式中匹配的对应名字的查询字符串的值的正则表达式组名字
None.gif  
-->
None.gif    
< handler  name ="news" >
None.gif        
< regex > /(? &lt; id &gt; [\d]+).shtml </ regex >
None.gif        
< aspxPath > detail.aspx </ aspxPath >
None.gif        
< params >
None.gif            
< param  name ="id"  valueRegexGroupName ="id" />
None.gif        
</ params >
None.gif    
</ handler >         
None.gif  
</ handlerSettings >

请大家看配置里面的注释。

有了配置节,我们就需要解析配置的类了,如下ConfigHandler用来读取配置节的信息,并将所有的配置信息实例化成ConfigItem 数组,然后放在这个类的一个静态数组中。

ContractedBlock.gif ExpandedBlockStart.gif
None.gifpublic class ConfigHandler:System.Configuration.IConfigurationSectionHandler
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
protected ConfigHandler()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
static private ConfigItem[] _handlerConfigArray;
InBlock.gif        [System.Xml.Serialization.XmlArrayItem(
"handler",typeof(ConfigItem))]
InBlock.gif        
static public ConfigItem[] HandlerConfigArray
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _handlerConfigArray;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
IConfigurationSectionHandler 成员#region IConfigurationSectionHandler 成员
InBlock.gif
InBlock.gif        
public object Create(object parent, object configContext, System.Xml.XmlNode section)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            XmlNodeList nodeList 
= section.SelectNodes("handler");
InBlock.gif            ArrayList configList 
= new ArrayList();
InBlock.gif            
foreach(XmlNode node in nodeList)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ConfigItem item 
= new ConfigItem();
InBlock.gif                item.Name 
= node.Attributes["name"].Value;
InBlock.gif                
InBlock.gif                XmlNode regexNode 
= node.SelectSingleNode("regex"); 
InBlock.gif                item.GlobalRegex 
= regexNode.InnerText;
InBlock.gif
InBlock.gif                XmlNode aspxNode 
= node.SelectSingleNode("aspxPath");
InBlock.gif                item.AspxPath 
= aspxNode.InnerText;
InBlock.gif
InBlock.gif                XmlNode paramsNode 
= node.SelectSingleNode("params");
InBlock.gif                
if(paramsNode != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    XmlNodeList paramNodeList 
= paramsNode.SelectNodes("param");
InBlock.gif
InBlock.gif                    ArrayList list 
= new ArrayList();
InBlock.gif                    
foreach(XmlNode paramNode in paramNodeList)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        ConfigParam p 
= new ConfigParam();
InBlock.gif                        p.Name 
= paramNode.Attributes["name"].Value;
InBlock.gif                        p.ValueRegexGroupName 
= paramNode.Attributes["valueRegexGroupName"].Value;
InBlock.gif
InBlock.gif                        list.Add(p);
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    item.Params 
= (ConfigParam[])list.ToArray(typeof(ConfigParam));
ExpandedSubBlockEnd.gif                }

InBlock.gif                configList.Add(item);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            _handlerConfigArray 
= (ConfigItem[])configList.ToArray(typeof(ConfigItem));
InBlock.gif
InBlock.gif            
InBlock.gif            
return null;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

ExpandedBlockEnd.gif    }

None.gif
None.gif    
public class ConfigItem
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public ConfigItem()dot.gif{}
InBlock.gif
InBlock.gif        
private string _name;
InBlock.gif        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_name = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private string _globalRegex;
InBlock.gif
InBlock.gif        
public string GlobalRegex
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _globalRegex;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_globalRegex = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string _aspxPath;
InBlock.gif        
public string AspxPath
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _aspxPath;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_aspxPath = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private ConfigParam[] _params;
InBlock.gif        
public ConfigParam[] Params
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _params;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_params = value;}
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif
None.gif    
public class ConfigParam
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
private string _name;
InBlock.gif
InBlock.gif        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_name = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private string _valueRegexGroupName;
InBlock.gif        
InBlock.gif        
public string ValueRegexGroupName
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return _valueRegexGroupName;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{_valueRegexGroupName = value;}
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


解析出了重写的配置信息,我们的主角就该出场了,从IHttpHandlerFactory 继承的HanderFactory

ContractedBlock.gif ExpandedBlockStart.gif HandlerFactory
None.gifpublic class HandlerFactory:IHttpHandlerFactory
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
public HandlerFactory()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
IHttpHandlerFactory 成员#region IHttpHandlerFactory 成员
InBlock.gif
InBlock.gif        
public void ReleaseHandler(IHttpHandler handler)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            url 
= url.ToLower();
InBlock.gif
InBlock.gif            
foreach(ConfigItem ci in ConfigHandler.HandlerConfigArray)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Regex regex 
= new Regex(ci.GlobalRegex,RegexOptions.IgnoreCase);
InBlock.gif                Match match 
= regex.Match(url);
InBlock.gif                
if(match.Success)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string queryString = string.Empty;
InBlock.gif
InBlock.gif                    
if(ci.Params != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
foreach(ConfigParam cp in ci.Params)dot.gif{
InBlock.gif                        queryString 
+= string.Format("{0}={1}&",cp.Name,match.Groups[cp.ValueRegexGroupName].Value);
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    
foreach(string queryKey in context.Request.QueryString.AllKeys)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
if(queryString.IndexOf("&" + queryKey + "="== -1 && queryString.IndexOf(queryKey + "="== -1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            queryString 
+= string.Format("{0}={1}&",queryKey,context.Request.QueryString[queryKey]);
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
InBlock.gif                    queryString 
= queryString.TrimEnd('&');
InBlock.gif
InBlock.gif                    context.RewritePath(url,
"",queryString);
InBlock.gif
InBlock.gif                    
return PageParser.GetCompiledPageInstance(url, context.Server.MapPath(ci.AspxPath), context);
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
InBlock.gif            ErrorHandler.RedirectFor400();
InBlock.gif
InBlock.gif            
return null;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

ExpandedBlockEnd.gif    }

 

我们只实现了接口的GetHandler方法首先我们需要逐个的用配置中的正则表达式去匹配传进来的Url,如果改配置项匹配了Url,那么就开始根据配置的参数项,提取url中的查询字符串的值,并组成一个查询字符串,需要注意的是查询字符串并不只是这一部分因为xxx.shtml还可能带有查询字符串的,所以我们还需要把这一部分的查询字符串附加到提取出来的查询字符串的后面,最后我们使用PageParser.GetCompiledPageInstance返回一个IHttpHandler的实例,到这儿基本上就结束了。 

当然我们还少不了要配置一下iis让.net去处理指定扩展名的请求。配置Web.config中的httpHandlers配置节。 

不过由于iis的先天问题,我们在使用虚拟服务器的时候就没有办法用Url重写了,郁闷ing,大家有没有什么好办法?

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值