1: Проблема удаления при перезаписи в asp.net1.1! ! !
Например, следующее регулярное выражение:
<Rules>
<Правило Рерайтера>
<ЛукФорс>
<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>
</ЛукФорс>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
</Правила>
Среди них 1 и 4 можно нормально сопоставить с соответствующей страницей
, но 2 и 3 вызовут ошибку http404! ! !
Причина кроется в потоке обработки самого IIS. Решение — переписать обработку ошибки 404 на самом сайте! ! !
1. Настройте URL-адрес для обработки ошибок 404 (настроено в IIS, конфигурация в web.config бесполезна для перезаписи)
2. Добавьте в раздел System.Web следующий раздел:
<httpHandlers>
<add verb="*" path="404.aspx" type="lt.Http404,lt"></add>
</httpHandlers>
<httpМодули>
<add type="lt.ReWriteModule,lt" name="ModuleRewriter" />
</httpModules>
Исходный код выглядит следующим образом:
общедоступный класс Http404:System.Web.IHttpHandler
{
общедоступный HTTP404()
{
//
// TODO: добавить сюда логику конструктора
//
}
#region Член IHttpHandler
public void ProcessRequest (контекст System.Web.HttpContext)
{
// TODO: добавить реализацию Http404.ProcessRequest
строка errorPath=context.Request.RawUrl.Split(новый символ[]{';'})[1];
строка appPath = context.Request.ApplicationPath;
int ipos=errorPath.IndexOf(appPath);
строка url=errorPath.Substring(ipos+appPath.Length);
// if(!url.EndsWith("/"))
// {
// URL+="/";
// }
// url+="index.html";
// context.Response.Write(url);
// context.RewritePath(url);
//context.Response.Write(url);
URL="~"+URL;
строка newUrl =lt.ReWriteModule.GetUrl(контекст,url);
//context.Response.Write(newUrl);
если (newUrl != ноль)
{
//cxt.Response.Filter = новый ResponseFilter(cxt.Response.Filter,cxt.Request.Path);
context.Response.Write("Запрошенный путь:" + URL);
context.Response.Write("<BR>");
context.Response.Write("Перенаправленный целевой URL: " + newUrl);
context.Response.Write("<BR>");
context.RewritePath(newUrl);
}
еще
{
context.Response.Write("Запрошенный вами ресурс не существует!!");
контекст.Ответ.Конец();
}
}
public bool IsReusable
{
получать
{
// TODO: добавить реализацию метода получения Http404.IsReusable
вернуть ложь;
}
}
////////////////Обработка httpModule в разделе конфигурации выглядит следующим образом:
public class ReWriteModule:System.Web.IHttpModule
{
общедоступный ReWriteModule()
{
//
// TODO: добавить сюда логику конструктора
//
}
#region Член IHttpModule
public void Init (контекст System.Web.HttpApplication)
{
// ЗАДАЧА: добавить реализацию ReWriteModule.Init
context.BeginRequest+=новый EventHandler(this.ReWrite);
}
частный статический System.Xml.XmlDocument ruleDoc = null;
частный статический System.Xml.XmlDocument GetRuleConfig (приложение System.Web.HttpContext)
{
если (ruleDoc == ноль)
{
RuleDoc = новый System.Xml.XmlDocument();
ruleDoc.Load(app.Server.MapPath("~/rule.xml"));
}
вернуть правилоДок;
}
общедоступная статическая строка GetUrl (System.Web.HttpContext cxt, путь к строке)
{
System.Xml.XmlDocument doc = GetRuleConfig(cxt);
System.Xml.XmlNodeList lst = doc.GetElementsByTagName("RewriterRule");
строка похлопывать="";
foreach (System.Xml.XmlNode и в списке)
{
System.Xml.XmlNodeList sub = nd.ChildNodes[0].ChildNodes;
foreach(System.Xml.XmlNode chk в суб)
{
pat = "^" + chk.InnerText+"$";
System.Text.RegularExpressions.Regex reg = новый System.Text.RegularExpressions.Regex(pat, System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
если (reg.IsMatch (путь))
{
return reg.Replace(path, nd.ChildNodes[1].InnerText);
}
}
}
вернуть ноль
}
;
Private void ReWrite (отправитель объекта, EventArgs e)
{
System.Web.HttpContext cxt =(отправитель как System.Web.HttpApplication).Context;
if (cxt.Request.ContentType != "изображение/pjpeg")
{
тип строки = cxt.Request.ContentType.ToLower();
строковый путь = cxt.Request.Path;
строка apppath = cxt.Request.ApplicationPath;
путь = путь.Удалить(0, apppath.Length);
путь = «~» + путь;
строка newUrl = GetUrl(cxt, path.TrimEnd().TrimStart());
если (newUrl != ноль)
{
//cxt.Response.Filter = новый ResponseFilter(cxt.Response.Filter,cxt.Request.Path);
cxt.Response.Write("Запрошенный путь:" + путь);
cxt.Response.Write("<BR>");
cxt.Response.Write("Перенаправленный целевой URL: " + newUrl);
cxt.Response.Write("<BR>");
cxt.RewritePath(newUrl);
}
//еще
//{
// cxt.Response.Write(cxt.Request.Path + "<BR>");
// cxt.Response.Write("Запрошенный вами ресурс не существует или у вас нет разрешения на доступ!");
// cxt.Response.Flush();
// cxt.Response.End();
//}
}
}
публичная недействительность Dispose()
{
// TODO: добавить реализацию ReWriteModule.Dispose
}
#конечныйрегион
}
---------rule.xml настраивается следующим образом:
<?xml version="1.0"coding="utf-8" ?>
<Правила>
<Правило Рерайтера>
<ЛукФорс>
<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>
</ЛукФорс>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
<Правило Рерайтера>
<ЛукФорс>
<LookFor>~/Pro.aspx?year=(d{4})&month=(d{2})</LookFor>
</ЛукФорс>
<SendTo>~/(d{4})/(d{2}).html</SendTo>
</RewriterRule>
<Правило Рерайтера>
<ЛукФорс>
<LookFor>~/pc</LookFor>
</ЛукФорс>
<SendTo>~/Test2.aspx</SendTo>
</RewriterRule>
<Правило Рерайтера>
<ЛукФорс>
<LookFor>~/index.html</LookFor>
<LookFor>~/default.html</LookFor>
</ЛукФорс>
<SendTo>~/default.aspx</SendTo>
</RewriterRule>
</Rules>
/////////Для изменений действий, вызванных перезаписью, обратитесь к написанной мной проблеме urlMappings в asp.net2.0! ! ! ! !