asp.net2.0의 urlMappings는 사용하기 매우 쉽지만 안타깝게도 정규식을 지원하지 않습니다. 그러나 다행히 IHttpModule을 사용하면
어떤 종류의 요청이든 먼저 IHttpModule을 거치게 되어 좋은 결과를 제공합니다. URL 재작성 기회:
다음은 제가 작성한 IHttpModule입니다.
using System;
System.Web을 사용하여
공용 클래스 ReWriteModule:IHttpModule
{
공개 ReWriteModule()
{
}
공개 재정의 문자열 ToString()
{
return this.GetType().ToString();
}
무효 IHttpModule.Dispose()
{
}
개인 정적 System.Xml.XmlDocument ruleDoc = null;
개인 정적 System.Xml.XmlDocument GetRuleConfig(System.Web.HttpContext 앱)
{
if (ruleDoc == null)
{
ruleDoc = new System.Xml.XmlDocument();
ruleDoc.Load(app.Server.MapPath("~/rule.xml"));
}
ruleDoc을 반환합니다.
}
공개 정적 문자열 GetUrl(System.Web.HttpContext cxt,문자열 경로)
{
System.Xml.XmlDocument doc = GetRuleConfig(cxt);
System.Xml.XmlNodeList lst= doc.GetElementsByTagName("RewriterRule");
문자열 패트="";
foreach(lst의 System.Xml.XmlNode nd)
{
System.Xml.XmlNodeList 하위 = nd.ChildNodes[0].ChildNodes;
foreach(하위의 System.Xml.XmlNode chk)
{
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(경로))
{
return reg.Replace(path, nd.ChildNodes[1].InnerText);
}
}
}
null을 반환
}
무효 IHttpModule.Init(HttpApplication 컨텍스트)
{
context.BeginRequest += 대리자(객체 보낸 사람, EventArgs e)
{
System.Web.HttpContext cxt = context.Context;
if(cxt.Request.ContentType != "이미지/pjpeg")
{
문자열 유형 = cxt.Request.ContentType.ToLower();
문자열 경로 = cxt.Request.Path;
문자열 apppath = cxt.Request.ApplicationPath;
경로 = 경로.제거(0, apppath.Length);
경로 = "~" + 경로;
string newUrl = GetUrl(cxt, path.TrimEnd().TrimStart());
if (newUrl != null)
{
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();
//}
}
};
}
}
URL이 다시 작성되면 원본 WEBFORM의 작업이 변경되어 쉽게 다음과 같은 문제가 발생할 수 있습니다.
구체적으로 무엇입니까? DX로 보면 알 수 있을 것 같아요! ! !
우리가 가진 것은 다음과 같이 구현된 ResponseFilter뿐입니다.
public class ResponseFilter:System.IO.Stream
{
공개 ResponseFilter(System.IO.Stream 싱크, 문자열 _str)
{
_싱크 = 싱크대;
//
// TODO: 여기에 생성자 논리를 추가합니다.
//
this.str = _str;
}
개인 문자열 str = "";
개인 System.IO.Stream _sink;
비공개 긴 _위치;
개인 System.Text.Encoding end=System.Text.Encoding.GetEncoding("GB18030");
개인 System.Text.StringBuilder oOutput = new System.Text.StringBuilder();
// Stream의 다음 멤버는 재정의되어야 합니다.
공개 재정의 bool CanRead
{
{참을 반환}을 얻습니다;
}
공개 재정의 bool CanSeek
{
{참을 반환}을 얻습니다;
}
공개 재정의 bool CanWrite
{
{참을 반환}을 얻습니다;
}
공개 재정의 긴 길이
{
{0을 반환}을 얻으십시오;
}
공개 재정의 긴 위치
{
{반환_위치}를 얻습니다.
설정 { _position = 값 }
}
공개 재정의 긴 탐색(긴 오프셋, System.IO.SeekOrigin 방향)
{
return _sink.Seek(오프셋, 방향);
}
공개 재정의 void SetLength(긴 길이)
{
_sink.SetLength(길이);
}
공개 재정의 무효 닫기()
{
_sink.Close();
}
공개 재정의 무효 Flush()
{
_sink.Flush();
}
공개 재정의 int Read(byte[] 버퍼, int 오프셋, int 개수)
{
return _sink.Read(버퍼, 오프셋, 개수);
}
// Write 메서드는 실제로 필터링을 수행합니다.
공개 재정의 무효 쓰기(바이트[] 버퍼, int 오프셋, int 개수)
{
string szBuffer = System.Text.UTF8Encoding.UTF8.GetString(버퍼, 오프셋, 개수);
string ap="action="";
int 위치=-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(데이터, 0, 데이터.길이);
}
또 다른
{
oOutput.Append(szBuffer);
}
//다음 단락을 사용하여 <Head></head> 사이의 내용을 수정할 수 있습니다.
//Regex oEndFile = new Regex("</head>", RegexOptions.IgnoreCase|RegexOptions.Compiled);
//if (oEndFile.IsMatch(szBuffer))
//{
// //데이터의 마지막 버퍼 추가
// //버퍼에 있는 데이터의 마지막 부분을 추가합니다.
// oOutput.Append(szBuffer);
// //클라이언트에 대한 완전한 응답을 돌려받습니다.
// //완전한 클라이언트 반환 데이터 전송
// 문자열 szCompleteBuffer = oOutput.ToString().ToLower();
// int ipos = szCompleteBuffer.IndexOf("<title>");
// int epos = szCompleteBuffer.IndexOf("</title>",ipos+7);
// 문자열 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");
// //일치하지 않으므로 원본 데이터를 씁니다.
// //일치하지 않으므로 소스 코드가 작성됩니다.
// 바이트[] 데이터 = System.Text.UTF8Encoding.UTF8.GetBytes(szCompleteBuffer);
// _sink.Write(data, 0, data.Length);
//}
//또 다른
//{
// oOutput.Append(szBuffer);
//}
}
}
//////대기 규칙은 xml 파일을 사용하여 다음과 같이 구성됩니다.
물론 web.config
<?xml version="1.0" 인코딩="utf-8"
의 사용자 정의 구성 섹션을 통해 구성할 수도 있습니다.? >
<규칙>
<리라이터규칙>
<찾아보기>
<찾아보기>~/(d{4})/(d{2}).html</찾아보기>
<찾아보기>~/(d{4})/(d{2})/</찾아보기>
<찾아보기>~/(d{4})/(d{2})</찾아보기>
<찾아보기>~/(d{4})/(d{2})/index.html</LookFor>
</LookFors>
<SendTo>~/Pro.aspx?year=$1&month=$2</SendTo>
</RewriterRule>
<리라이터규칙>
<찾아보기>
<LookFor>~/pc</LookFor>
</LookFors>
<SendTo>~/Test2.aspx</SendTo>
</RewriterRule>
</규칙>
//이 규칙은 잘 작성되지 않았습니다. 예를 들어 첫 번째 규칙은 정규식으로 수행할 수 있습니다. 그런데 지금은 어떻게 써야 좋을지 모르겠네요. 캡쳐 방지 그룹이라는 개념을 좀 써야 할 것 같네요. !