Die URLMappings in asp.net2.0 sind sehr einfach zu verwenden, unterstützen jedoch leider keine regulären Ausdrücke. Wenn Sie jedoch IHttpModule verwenden,
wird unabhängig von der Art der Anforderung zuerst IHttpModule durchlaufen, was eine gute Sache ist Möglichkeit zum Umschreiben von URLs:
Das Folgende ist ein IHttpModule, das ich geschrieben habe:
using System;
mit System.Web;
öffentliche Klasse ReWriteModule:IHttpModule
{
öffentliches ReWriteModule()
{
}
öffentlicher Override-String ToString()
{
return this.GetType().ToString();
}
void IHttpModule.Dispose()
{
}
private static System.Xml.XmlDocument RuleDoc = null;
privates statisches 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;
}
öffentlicher statischer 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 und 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(Objektsender, 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("Angeforderter Pfad:" + Pfad);
cxt.Response.Write("<BR>");
cxt.Response.Write("Umgeleitete Ziel-URL: " + newUrl);
cxt.Response.Write("<BR>");
cxt.RewritePath(newUrl);
} // Wird bei Bedarf zur Bearbeitung aller Anfragen verwendet
//anders
//{
// cxt.Response.Write(cxt.Request.Path + "<BR>");
// cxt.Response.Write("Die von Ihnen angeforderte Ressource existiert nicht oder Sie haben keine Zugriffsberechtigung!");
// cxt.Response.Flush();
// cxt.Response.End();
//}
}
};
}
}
Da sich die Aktion im ursprünglichen WEBFORM ändert, sobald die URL neu geschrieben wird, kann dies leicht dazu führen, dass die angeforderte Ressource nicht existiert
. Was konkret? Es wird klar, wenn Sie einen Blick darauf werfen! ! !
Alles, was wir haben, ist dieser ResponseFilter, der wie folgt implementiert ist:
öffentliche Klasse ResponseFilter:System.IO.Stream
{
public ResponseFilter(System.IO.Stream sink,string _str)
{
_sink = sinken;
//
// TODO: Konstruktorlogik hier hinzufügen
//
this.str = _str;
}
private Zeichenfolge 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();
// Die folgenden Mitglieder von Stream müssen überschrieben werden.
öffentlicher Override-Bool CanRead
{
get { return true }
}
public override bool CanSeek
{
get { return true }
}
public override bool CanWrite
{
get { return true }
}
public überschreibt lange Länge
{
get { return 0 }
}
public override long Position
{
get { return _position }
set { _position = value }
}
public override long Seek (langer Offset, System.IO.SeekOrigin-Richtung)
{
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);
}
// Die Write-Methode übernimmt tatsächlich die Filterung.
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);
data = System.Text.UTF8Encoding.UTF8.GetBytes(szBuffer);
_sink.Write(data, 0, data.Length);
}
anders
{
oOutput.Append(szBuffer);
}
// Der folgende Absatz kann verwendet werden, um den Inhalt zwischen <Head></head>;
//Regex oEndFile = new Regex("</head>", RegexOptions.IgnoreCase|RegexOptions.Compiled);
//if (oEndFile.IsMatch(szBuffer))
//{
// //Den letzten Datenpuffer anhängen
// //Den letzten Teil der Daten im Puffer anhängen
// oOutput.Append(szBuffer);
// //Erhalten Sie die vollständige Antwort für den Client zurück
// //Komplette Client-Rückgabedaten übertragen
// 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");
// //Keine Übereinstimmung, daher Originaldaten ausschreiben
// //Keine Übereinstimmung, daher wird Quellcode geschrieben
// byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(szCompleteBuffer);
// _sink.Write(data, 0, data.Length);
//}
//anders
//{
// oOutput.Append(szBuffer);
//}
}
}
//////Die Warteregeln werden wie folgt mithilfe von XML-Dateien konfiguriert.
Sie können dies natürlich auch über einen benutzerdefinierten Konfigurationsabschnitt in web.config tun
<?xml version="1.0" binding="utf-8" ? >
<Regeln>
<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>
</Regeln>
//Diese Regel ist nicht gut geschrieben. Die erste kann beispielsweise mit einem regulären Ausdruck ausgeführt werden. Aber ich weiß im Moment nicht, wie ich es richtig schreiben soll. Es scheint, dass ich über so etwas nachdenke. !