L'urlMappings dans asp.net2.0 est très simple à utiliser, mais malheureusement il ne prend pas en charge les expressions régulières. Cependant, heureusement, si vous utilisez IHttpModule,
quel que soit le type de requête, il passera d'abord par IHttpModule, ce qui fournit une bonne solution. opportunité de réécriture d'URL :
Ce qui suit est un IHttpModule que j'ai écrit :
using System;
en utilisant System.Web ;
classe publique ReWriteModule : IHttpModule
{
public ReWriteModule()
{
}
chaîne de remplacement publique ToString()
{
renvoie this.GetType().ToString();
}
annuler IHttpModule.Dispose()
{
}
private static System.Xml.XmlDocument RuleDoc = null ;
privé statique System.Xml.XmlDocument GetRuleConfig (application System.Web.HttpContext)
{
si (ruleDoc == null)
{
RuleDoc = new System.Xml.XmlDocument();
RuleDoc.Load(app.Server.MapPath("~/rule.xml"));
}
retourner le RuleDoc ;
}
chaîne statique publique GetUrl (System.Web.HttpContext cxt, chemin de chaîne)
{
System.Xml.XmlDocument doc = GetRuleConfig(cxt);
System.Xml.XmlNodeList lst= doc.GetElementsByTagName("RewriterRule");
chaîne pat="";
foreach (System.Xml.XmlNode et dans lst)
{
System.Xml.XmlNodeList sub = nd.ChildNodes[0].ChildNodes;
foreach (System.Xml.XmlNode chk dans le sous)
{
pat = "^" + chk.InnerText+"$";
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(pat, System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
si (reg. IsMatch (chemin))
{
return reg.Replace(path, nd.ChildNodes[1].InnerText);
}
}
}
renvoie nul ;
}
void IHttpModule.Init (contexte HttpApplication)
{
context.BeginRequest += délégué (expéditeur de l'objet, EventArgs e)
{
System.Web.HttpContext cxt = contexte.Context;
if (cxt.Request.ContentType != "image/pjpeg")
{
type de chaîne = cxt.Request.ContentType.ToLower();
chemin de chaîne = cxt.Request.Path ;
chaîne apppath = cxt.Request.ApplicationPath ;
chemin = chemin.Remove(0, apppath.Length);
chemin = "~" + chemin ;
string newUrl = GetUrl(cxt, path.TrimEnd().TrimStart());
si (nouvelleUrl != null)
{
cxt.Response.Filter = nouveau ResponseFilter(cxt.Response.Filter,cxt.Request.Path);
cxt.Response.Write("Chemin demandé :" + chemin);
cxt.Response.Write("<BR>");
cxt.Response.Write("URL de destination redirigée : " + newUrl);
cxt.Response.Write("<BR>");
cxt.RewritePath(newUrl);
} // Utilisé si nécessaire pour gérer toutes les requêtes
//autre
//{
// cxt.Response.Write(cxt.Request.Path + "<BR>");
// cxt.Response.Write("La ressource que vous avez demandée n'existe pas ou vous n'avez aucune autorisation pour y accéder !");
// cxt.Response.Flush();
// cxt.Response.End();
//}
}
} ;
}
}
Puisqu'une fois l'URL réécrite, l'Action dans le WEBFORM d'origine changera, ce qui peut facilement causer : la ressource demandée n'existe pas
. Quoi de précis ? Ce sera clair si vous y jetez un oeil ! ! !
Tout ce que nous avons est ce ResponseFilter, qui est implémenté comme suit,
classe publique ResponseFilter:System.IO.Stream
{
public ResponseFilter (récepteur System.IO.Stream, chaîne _str)
{
_évier = évier ;
//
// TODO : ajouter la logique du constructeur ici
//
this.str = _str;
}
chaîne privée str = "" ;
système privé.IO.Stream _sink ;
position longue privée ;
private System.Text.Encoding end=System.Text.Encoding.GetEncoding("GB18030");
private System.Text.StringBuilder oOutput = new System.Text.StringBuilder();
// Les membres suivants de Stream doivent être remplacés.
public override booléen CanRead
{
obtenir { retourner vrai }
}
remplacement public bool CanSeek
{
obtenir { retourner vrai }
}
remplacement public bool CanWrite
{
obtenir { retourner vrai }
}
remplacement public longue longueur
{
obtenir { retourner 0 ;
}
public override Position longue
{
obtenir {return_position;}
définir { _position = valeur }
}
remplacement public longue recherche (décalage long, direction System.IO.SeekOrigin)
{
return _sink.Seek (décalage, direction);
}
remplacement public void SetLength (longue longueur)
{
_sink.SetLength(longueur);
}
remplacement public void Close()
{
_sink.Close();
}
remplacement public void Flush()
{
_sink.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _sink.Read (buffer, offset, count);
}
// La méthode Write effectue réellement le filtrage.
remplacement public void Write (tampon d'octet [], décalage int, nombre int)
{
chaîne szBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
chaîne ap="action="";
int pos=-1 ;
si ((pos=szBuffer.IndexOf(ap) )!= -1)
{
int epos = szBuffer.IndexOf(""", pos + ap.Length+1);
si (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(données, 0, données.Longueur);
}
autre
{
oOutput.Append(szBuffer);
}
//Le paragraphe suivant peut être utilisé pour modifier le contenu entre <Head></head>;
//Regex oEndFile = new Regex("</head>", RegexOptions.IgnoreCase|RegexOptions.Compiled);
//if (oEndFile.IsMatch(szBuffer))
//{
// //Ajouter le dernier tampon de données
// //Ajouter la dernière partie des données dans le tampon
// oOutput.Append(szBuffer);
// //Récupère la réponse complète du client
// //Transmettre les données complètes de retour du client
// chaîne szCompleteBuffer = oOutput.ToString().ToLower();
// int ipos = szCompleteBuffer.IndexOf("<titre>");
// int epos = szCompleteBuffer.IndexOf("</title>",ipos+7);
// chaîne 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");
// //Aucune correspondance, donc écrivez les données originales
// //Aucune correspondance, donc le code source est écrit
// byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(szCompleteBuffer);
// _sink.Write(data, 0, data.Length);
//}
//autre
//{
// oOutput.Append(szBuffer);
//}
}
}
//////Les règles d'attente sont configurées comme suit à l'aide de fichiers XML ;
bien sûr, vous pouvez également le faire via une section de configuration personnalisée dans web.config
<?xml version="1.0" encoding="utf-8" ?>
<Règles>
<Règle de réécriture>
<Recherches>
<LookFor>~/(d{4})/(d{2}).html</LookFor>
<Recherche>~/(d{4})/(d{2})/</Recherche>
<LookFor>~/(d{4})/(d{2})</LookFor>
<LookFor>~/(d{4})/(d{2})/index.html</LookFor>
</Recherche>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
<Règle de réécriture>
<Recherches>
<Recherche>~/pc</Recherche>
</Recherche>
<SendTo>~/Test2.aspx</SendTo>
</RewriterRule>
</Règles>
//Cette règle n'est pas bien écrite. Par exemple, la première peut être effectuée avec une expression régulière. Mais je ne sais pas comment l'écrire correctement pour le moment. Il semble que je doive utiliser un concept de groupe anti-capture. Je pense à ce genre de choses ! !