1 : Le problème de suppression lors de la réécriture dans asp.net1.1 ! ! !
Comme l'expression régulière suivante :
<Rules>
<Règle de réécriture>
<Recherches>
<LookFor>~/(d{4})/(d{2}).html</LookFor>---------<1>
<LookFor>~/(d{4})/(d{2})/</LookFor>--------------<2>
<LookFor>~/(d{4})/(d{2})</LookFor>---------------<3>
<LookFor>~/(d{4})/(d{2})/index.html</LookFor>----<4>
</Recherche>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
</Rules>
Parmi eux, 1 et 4 peuvent être mappés normalement à la page correspondante
, mais 2 et 3 provoqueront une erreur http404 ! ! !
La raison réside dans le flux de traitement d'IIS lui-même. La solution est de réécrire le traitement des erreurs 404 sur le site Web lui-même ! ! !
1 : Personnaliser l'URL de gestion des erreurs 404 (configurée dans IIS, la configuration dans web.config est inutile pour la réécriture)
2 : Ajouter la section suivante à la section System.Web :
<httpHandlers>
<add verb="*" path="404.aspx" type="lt.Http404,lt"></add>
</httpGestionnaires>
<Moduleshttp>
<add type="lt.ReWriteModule,lt" name="ModuleRewriter" />
</httpModules>
Le code source est le suivant :
classe publique Http404:System.Web.IHttpHandler
{
public Http404()
{
//
// TODO : ajouter la logique du constructeur ici
//
}
#region IHttpHandler membre
public void ProcessRequest (contexte System.Web.HttpContext)
{
// TODO : Ajouter l'implémentation de Http404.ProcessRequest
string errorPath=context.Request.RawUrl.Split(new char[]{';'})[1];
chaîne appPath=context.Request.ApplicationPath ;
int ipos=errorPath.IndexOf(appPath);
string url=errorPath.Substring(ipos+appPath.Length );
// si(!url.EndsWith("/"))
// {
//url+="/";
// }
// url+="index.html";
// contexte.Response.Write(url);
// contexte.RewritePath(url);
//context.Response.Write(url);
url="~"+url;
chaîne newUrl =lt.ReWriteModule.GetUrl(context,url);
//context.Response.Write(newUrl);
si (nouvelleUrl != null)
{
//cxt.Response.Filter = nouveau ResponseFilter(cxt.Response.Filter,cxt.Request.Path);
context.Response.Write("Chemin demandé :" + url);
contexte.Response.Write("<BR>");
context.Response.Write("URL de destination redirigée : " + newUrl);
contexte.Response.Write("<BR>");
contexte.RewritePath(newUrl);
}
autre
{
context.Response.Write("La ressource que vous avez demandée n'existe pas !!");
contexte.Response.End ();
}
}
public bool EstRéutilisable
{
obtenir
{
// À FAIRE : Ajouter l'implémentation du getter Http404.IsReusable
renvoie faux ;
}
}
/////////////////Le traitement du httpModule dans la section de configuration est le suivant :
classe publique ReWriteModule:System.Web.IHttpModule
{
public ReWriteModule()
{
//
// TODO : ajouter la logique du constructeur ici
//
}
#region IHttpModule membre
public void Init (contexte System.Web.HttpApplication)
{
// À FAIRE : Ajouter l'implémentation de ReWriteModule.Init
context.BeginRequest+=new EventHandler(this.ReWrite);
}
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 ;
}
private void ReWrite (expéditeur d'objet, EventArgs e)
{
System.Web.HttpContext cxt =(expéditeur en tant que System.Web.HttpApplication).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);
}
//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();
//}
}
}
public void Disposer()
{
// À FAIRE : Ajouter l'implémentation de ReWriteModule.Dispose
}
#endregion
}
---------rule.xml est configuré comme suit :
<?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>
<LookFor>~/Pro.aspx?year=(d{4})&month=(d{2})</LookFor>
</Recherche>
<SendTo>~/(d{4})/(d{2}).html</SendTo>
</RewriterRule>
<Règle de réécriture>
<Recherches>
<Recherche>~/pc</Recherche>
</Recherche>
<SendTo>~/Test2.aspx</SendTo>
</RewriterRule>
<Règle de réécriture>
<Recherches>
<LookFor>~/index.html</LookFor>
<LookFor>~/default.html</LookFor>
</Recherche>
<SendTo>~/default.aspx</SendTo>
</RewriterRule>
</Rules>
/////////Pour les changements d'action provoqués par la réécriture, veuillez vous référer au problème de urlMappings dans asp.net2.0 écrit par moi ! ! ! ! !