Urlmappings in ASP. net2.0 is very easy to use. Unfortunately, regular expressions are not supported for the time being. However, if ihttpmodule is used
No matter what kind of request will first pass through the ihttpmodule, this provides a good opportunity for URL rewriting:
Here is an ihttpmodule I wrote:
using System;
using System.Web;
public class ReWriteModule:IHttpModule
{
public ReWriteModule()
{
}
public override string ToString()
{
return this.GetType().ToString();
}
void IHttpModule.Dispose()
{
}
private static System.Xml.XmlDocument ruleDoc = null;
private static System.Xml.XmlDocument GetRuleConfig(System.Web.HttpContext app)
{
if (ruleDoc == null)
{
ruleDoc = new System.Xml.XmlDocument();
ruleDoc.Load(app.Server.MapPath("~/rule.xml"));
}
return ruleDoc;
}
public static string GetUrl(System.Web.HttpContext cxt,string path)
{
System.Xml.XmlDocument doc = GetRuleConfig(cxt);
System.Xml.XmlNodeList lst= doc.GetElementsByTagName("RewriterRule");
string pat="";
foreach (System.Xml.XmlNode nd in lst)
{
System.Xml.XmlNodeList sub = nd.ChildNodes[0].ChildNodes;
foreach(System.Xml.XmlNode chk in sub)
{
pat = "^" + chk.InnerText+"$";
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(pat, System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if(reg.IsMatch(path))
{
return reg.Replace(path, nd.ChildNodes[1].InnerText);
}
}
}
return null;
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += delegate(object sender, EventArgs e)
{
System.Web.HttpContext cxt = context.Context;
if (cxt.Request.ContentType != "image/pjpeg")
{
string type = cxt.Request.ContentType.ToLower();
string path = cxt.Request.Path;
string apppath = cxt.Request.ApplicationPath;
path = path.Remove(0, apppath.Length);
path = "~" + path;
String newurl = geturl (cxt, path. trimend (). trimstart ());
If (newurl! = NULL)
{
Cxt. response. Filter = new responsefilter (cxt. response. filter, cxt. Request. Path );
Cxt. response. Write ("Request Path:" + path );
Cxt. response. Write ("<br> ");
Cxt. response. Write ("redirection destination URL:" + newurl );
Cxt. response. Write ("<br> ");
Cxt. rewritepath (newurl );
} // Used to process all requests
// Else
//{
// Cxt. response. Write (cxt. Request. Path + "<br> ");
// Cxt. response. Write ("The resource you requested does not exist or you are not authorized to access it! ");
// Cxt. response. Flush ();
// Cxt. response. End ();
//}
}
};
}
} Once URL rewriting is performed, the action in the original webform will change, which may easily cause the requested resource to be non-existent.
How is it? Look At DX !!!
All have this responsefilter, And the implementation is as follows,
Public class responsefilter: system. Io. Stream
{
Public responsefilter (system. Io. Stream sink, string _ Str)
{
_ Sink = sink;
//
// Todo: add the constructor logic here
//
This. Str = _ STR;
}
Private string STR = "";
Private system. Io. Stream _ sink;
Private long _ position;
Private system. Text. Encoding end = system. Text. encoding. getencoding ("gb18030 ");
Private system. Text. stringbuilder ooutput = new system. Text. stringbuilder ();
// The following members of stream must be overriden.
Public override bool Canread
{
Get {return true ;}
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override long Length
{
get { return 0; }
}
public override long Position
{
get { return _position; }
set { _position = value; }
}
public override long Seek(long offset, System.IO.SeekOrigin direction)
{
return _sink.Seek(offset, direction);
}
public override void SetLength(long length)
{
_sink.SetLength(length);
}
public override void Close()
{
_sink.Close();
}
public override void Flush()
{
_sink.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _sink.Read(buffer, offset, count);
}
// The Write method actually does the filtering.
public override void Write(byte[] buffer, int offset, int count)
{
string szBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
string ap="action=\"";
int pos=-1;
if ((pos=szBuffer.IndexOf(ap) )!= -1)
{
int epos = szBuffer.IndexOf("\"", pos + ap.Length+1);
if (epos != -1)
{
szBuffer= szBuffer.Remove(pos + ap.Length, epos - pos - ap.Length);
}
szBuffer = szBuffer.Insert(pos + ap.Length, this.str);
byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(szBuffer);
_sink.Write(data, 0, data.Length);
}
else
{
oOutput.Append(szBuffer);
}
// The following section can be used to modify the content between // RegEx oendfile = new RegEx ("// If (oendfile. ismatch (szbuffer ))
//{
/// Append the last buffer of data
//// Append the last part of the buffer
// Ooutput. append (szbuffer );
/// Get back the complete response for the client
//// Return the complete data returned by the client
// String szcompletebuffer = ooutput. tostring (). tolower ();
// Int IPOs = szcompletebuffer. indexof ("<title> ");
// Int EPOS = szcompletebuffer. indexof ("</title>", IPOs + 7 );
// String sp = szcompletebuffer. substring (IPOs + 7, EPOS-IPOS );
// Szcompletebuffer = szcompletebuffer. Remove (IPOs + 7, sp. Length-7 );
// Szcompletebuffer = szcompletebuffer. insert (IPOs + 7, "DHZ ");
/// Szcompletebuffer = szcompletebuffer. Replace (SP, "DHZ ");
/// No match, so write out original data
//// No matching, so the source code is written.
// Byte [] DATA = system. Text. utf8encoding. utf8.getbytes (szcompletebuffer );
// _ Sink. Write (data, 0, Data. Length );
//}
// Else
//{
// Ooutput. append (szbuffer );
//}
}
}
///// While the rewait rule is configured in an XML file as follows;
Of course, you can also use the custom configuration section in Web. config.
<?xml version="1.0" encoding="utf-8" ?>
<Rules>
<RewriterRule>
<LookFors>
<LookFor>~/(\d{4})/(\d{2})\.html</LookFor>
<LookFor>~/(\d{4})/(\d{2})/</LookFor>
<LookFor>~/(\d{4})/(\d{2})</LookFor>
<LookFor>~/(\d{4})/(\d{2})/index.html</LookFor>
</LookFors>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
<RewriterRule>
<LookFors>
<LookFor>~/pc</LookFor>
</LookFors>
<SendTo>~/Test2.aspx</SendTo>
</RewriterRule>
</Rules>
// This rule is not well written. For example, you can use a regular expression as the first rule. But I don't know how to write it at the moment. It seems that I want to use the anti-capturing group concept. I'm thinking about this stuff !!