一个完整的ASP.NET 2.0 URL重写方案[翻译](3)

可以看到,这样就可以通过RewriteContext.Current 集合来访问 “虚拟路径参数”了,所有的参数都被指定成了虚拟路径或页面,而不是像查询字符串那样了。

重写 URL

接下来,让我们尝试重写。首先,我们要读取配置文件中的重写规则。其次,我们要检查那些在 URL 中与规则不符的部分,如果有,进行重写并以适当的页执行。

创建一个 HttpModule:

class RewriteModule : IHttpModule
{

public void Dispose() { }
public void Init(HttpApplication context)

{}

}

当我们添加 RewriteModule_BeginRequest 方法以处理不符合规则的 URL时,我们要检查给定的 URL 是否包含参数,然后调用 HttpContext.Current.RewritePath 来进行控制并给出合适的 ASP.NET 页。

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

using System.Configuration;

using System.Xml;

using System.Text.RegularExpressions;

using System.Web.UI;

using System.IO;

using System.Collections.Specialized;

namespace RewriteModule

{

class RewriteModule : IHttpModule

{

public void Dispose() { }

public void Init(HttpApplication context)

{

// it is necessary to

context.BeginRequest += new EventHandler(
                 RewriteModule_BeginRequest);

}

void RewriteModule_BeginRequest(object sender, EventArgs e)

{

RewriteModuleSectionHandler cfg =
(RewriteModuleSectionHandler)
ConfigurationManager.GetSection
("modulesSection/rewriteModule");

// module is turned off in web.config

if (!cfg.RewriteOn) return;

string path = HttpContext.Current.Request.Path;

// there us nothing to process

if (path.Length == 0) return;

// load rewriting rules from web.config

// and loop through rules collection until first match

XmlNode rules = cfg.XmlSection.SelectSingleNode("rewriteRules");

foreach (XmlNode xml in rules.SelectNodes("rule"))

{

try

{

Regex re = new Regex(
                     cfg.RewriteBase + xml.Attributes["source"].InnerText,
                     RegexOptions.IgnoreCase);

Match match = re.Match(path);

if (match.Success)

{

path = re.Replace(
                             path,
                             xml.Attributes["destination"].InnerText);

if (path.Length != 0)

{

// check for QueryString parameters

if(HttpContext.Current.Request.QueryString.Count != 0)

{

// if there are Query String papameters

// then append them to current path

string sign = (path.IndexOf('?') == -1) ? "?" : "&";

path = path + sign +
                          HttpContext.Current.Request.QueryString.ToString();

}

// new path to rewrite to

string rew = cfg.RewriteBase + path;

// save original path to HttpContext for further use

HttpContext.Current.Items.Add(

"OriginalUrl",

HttpContext.Current.Request.RawUrl);

// rewrite

HttpContext.Current.RewritePath(rew);

}

return;

}

}

catch (Exception ex)

{

throw (new Exception("Incorrect rule.", ex));

}

}

return;

}

}

}

这个方法必须注册:

public void Init(HttpApplication context)

{

context.BeginRequest += new EventHandler(RewriteModule_BeginRequest);

}

但这些仅仅完成了一半,因为重写模块还要处理表单的回发和虚拟路径参数集合,而这段代码中你会发现并没处理这些。让我们先把虚拟路径参数放到一边,先来正确地处理最主要的回发。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjjpgs.html