오늘 이메일을 받았는데 UpdatePanel이 UrlRewrite와 결합되면 왜 문제가 발생하는지 질문을 받았습니다. 이전에 UrlRewrite에서도 UpdatePanel을 사용한 적이 있었고 문제가 없었기 때문에 처음에는 심각하게 받아들이지 않았습니다. 그런데 상대방으로부터 패키지된 코드를 받아본 결과 실제로 문제가 재발했다는 것을 알게 되었는데, 대상 페이지에 직접 접속했다면 문제가 없었을 것입니다. 왜냐하면 저는 당시 회사에 있었고 오류의 원인을 주의 깊게 조사하지 않았기 때문입니다. 집에 오는 길에 마음 속으로 UpdatePanel의 구현 과정을 계속해서 시뮬레이션해 보았지만 아무런 문제도 발견되지 않았습니다. 결국 나는 버스에 앉아 노트북을 열고 주의 깊게 문제를 찾아보았다. 버스가 심하게 흔들리고 있었는데 다행히 토하기 전에 드디어 문제를 발견했습니다.
문제 재현:
이제 문제를 재현하겠습니다. 원본 코드에서는 단순화를 위해 가장 일반적인 UrlRewrite 메서드를 사용하여 동일한 효과를 얻었으며, NBear에 익숙하지 않은 일부 친구(저 포함)를 피하고 기사의 이해를 방해하려고 했습니다. 콘텐츠.
먼저 새로운 ASP.NET AJAX 지원 웹 사이트를 만듭니다. 다음 내용으로 ~/SubFolder/Target.aspx 파일을 만듭니다. ~
/SubFolder/Target.aspx
<html xmlns=" http://www.w3.org/1999/xhtml " >
<head runat="서버">
<title>대상 페이지</title>
</head>
<본문>
<form id="form1" runat="서버">
<asp:ScriptManager ID="ScriptManager1" runat="서버">
</asp:스크립트매니저>
<asp:UpdatePanel ID="UpdatePanel1" runat="서버">
<컨텐츠템플릿>
<%= DateTime.Now.ToString() %>
<asp:Button ID="Button1" runat="server" Text="새로 고침" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
그런 다음 Global.asax를 만들고, Application_BeginRequest 메서드를 제공하고, 다음과 같이 Url Rewrite를 구현합니다.
Global.asax의 Application_BeginRequest 메서드
void Application_BeginRequest(객체 전송자, EventArgs e)
{
HttpContext context = (HttpApplication으로 보낸 사람).Context;
if (context.Request.Path.Contains("Source.aspx"))
{
context.RewritePath("SubFolder/Target.aspx", false);
}
}
이런 방식으로 ~/Source.aspx 파일에 액세스하면 ~/SubFolder/Target.aspx로 다시 작성되고 페이지를 열면 모든 것이 정상입니다.
새로 고침 버튼을 클릭하면 시간이 업데이트됩니다. 그런 다음 버튼을 다시 클릭하면 오류가 발생했습니다. "Sys.WebForms.PageRequestManagerServerErrorException: 서버에서 요청을 처리하는 동안 알 수 없는 오류가 발생했습니다. 서버에서 반환된 상태 코드는 12031입니다."
문제 분석:
이 문제의 원인은 Url Rewrite가 양식에서 제출한 주소를 업데이트하고 UpdatePanel이 주소 변경 사항을 페이지에 반영하기 때문입니다.
페이지를 처음 열면 페이지의 소스 파일에 있는 <form /> 요소의 동작이 더 이상 우리가 액세스한 Source.aspx가 아니라 Url Rewrite 이후의 대상 파일임을 알 수 있습니다
. 양식 요소 중 대상 페이지가 있습니다.
...
<form name="form1" method="post" action="SubFolder/Target.aspx" id="form1">
...
</form>
...
다행히도 부분 렌더링을 사용하면 "대상"이 올바른 한 UpdatePanel은 계속해서 데이터를 올바르게 보내고 받을 수 있으며 페이지를 업데이트할 수 있습니다. 따라서 새로 고침 버튼을 클릭하면 페이지가 올바르게 업데이트됩니다. 그러나 양식 요소의 동작도 변경되었습니다. 이는 Web Development Helper 및 IE Dev Toolbar를 사용하여 한 눈에 볼 수 있습니다.
비동기 PostBack을 수행할 때 ~/SubFolder/Target.aspx에 직접 액세스했으므로 생성된 Form 개체의 작업 값은 Target.aspx입니다. 결과적으로 UpdatePanel은 클라이언트 양식 요소의 작업을 부지런히 수정했습니다. 이렇게 하면 다시 제출할 때 존재하지 않는 페이지에 액세스할 수 있게 되며 오류는 불가피합니다.
문제 해결:
이제 문제를 발견했으므로 자연스럽게 쉽게 문제를 해결할 수 있습니다. Sys.Application의 로드 이벤트에만 응답하면 됩니다. 페이지가 처음 로드될 때와 각 부분 렌더링 이후에 페이지에서 양식 요소의 작업 속성을 수정할 수 있습니다. , 다음과 같습니다:
해당 Sys.Application 로드 이벤트
Sys.Application.add_load(함수()
{
var form = Sys.WebForms.PageRequestManager.getInstance()._form;
form._initialAction = form.action = window.location.href;
});
페이지의 양식 요소를 왜 이런 방식으로 얻어야 하는지, _initialAction이 무엇인지, 왜 설정해야 하는지는 UpdatePanel 구현과 관련되므로 여기서는 설명하지 않겠습니다. 이러한 작은 코드 조각이 페이지에 배치되기만 하면 이 문제는 해결됩니다.
심층 질문:
이 문제의 원인은 실제로 Url Rewrite 후 양식 요소의 동작이 클라이언트가 요청한 주소가 아니라 Url Rewrite의 대상 주소이기 때문입니다. Partial Rendering을 사용하지 않고 가장 전통적인 PostBack을 사용한다면 페이지 기능은 손상되지 않지만 PostBack 이후에 사용자는 주소 표시줄의 내용이 변경되어 바로 대상 주소가 되는 것을 발견하게 됩니다. 이것은 우리가 보고 싶은 결과가 아닙니다. 이제 다시 작성되었으니 끝까지 다시 작성해 보겠습니다. 물론 위에서 언급한 방법을 계속 사용할 수 있고 JavaScript를 사용하여 양식 요소의 작업을 수정할 수 있지만 이 방법은 충분히 "아름답지" 않으며 사용자는 HTML 소스에서 Url Rewrite의 대상 주소를 볼 수도 있습니다. 파일이 아니고 ?
서버 측에서 Form의 작업을 설정할 수 있다면 좋겠지만 불행하게도 System.Web.UI.HtmlControls.HtmlForm 클래스에서는 이를 허용하지 않습니다. 하지만 다행스럽게도 우리는 ASP.NET을 사용하고 객체 지향 프로그래밍 모델을 사용합니다. 따라서 System.Web.UI.HtmlControls.HtmlForm을 "상속"하고 자체 Form 컨트롤을 구현합니다.
HtmlForm 클래스를 상속하여 자체 From을 구현합니다.
네임스페이스 ActionlessForm {
공개 클래스 양식 : System.Web.UI.HtmlControls.HtmlForm
{
보호된 재정의 무효 RenderAttributes(HtmlTextWriter 작가)
{
writer.WriteAttribute("이름", this.Name);
base.Attributes.Remove("이름");
writer.WriteAttribute("메서드", this.Method);
base.Attributes.Remove("메서드");
this.Attributes.Render(writer);
base.Attributes.Remove("action");
if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}
그런 다음 페이지에서 사용할 수 있습니다. 물론, 그 전에 페이지(또는 Web.config)에 등록해야 합니다.
자체 구현된 양식을 사용하세요.
<%@ 등록 TagPrefix="skm" Namespace="ActionlessForm"
어셈블리="ActionlessForm" %>
...
<skm:Form id="Form1" method="post" runat="서버">
...
</skm:양식>
...
이 시점에서는 더 이상 페이지에 "영리한" JavaScript를 작성할 필요가 없습니다. Url Rewrite 후 양식 요소의 작업 문제가 해결되었습니다.
("심층 질문"은 MSDN의 이전 기사( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp )의 일부를 참조하십시오.)
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/27/updatepanel_with_url_rewrite.html