ASP.NET 포스트백 이벤트 유효성 검사 기능에 관한 Workaround

참으로 어렵게 알아낸 해결 방법 하나를 소개하고자 합니다. 지금 이야기하려는 내용은 ASP.NET 2.0 버전부터 새롭게 추가된 포스트백 이벤트 유효성 검사 기능에 관한 내용입니다. 이 기능은 기본적으로 의도하지 않은 잘못된 입력 값을 원천적으로 차단하기 위한 보안 정책입니다만, 이벤트 버블링이 필요한 경우 호환성 문제를 유발하기도 합니다. 아래에 나열된 컨트롤에 해당되지 않을 경우 이러한 호환성 문제를 겪을 수 있습니다. (http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx 자료 인용)




































































HtmlAnchor HtmlButton HtmlInputButton
HtmlInputCheckBox HtmlInputHidden HtmlInputImage
HtmlInputText HtmlInputPassword HtmlInputRadioButton
HtmlInputReset HtmlInputSubmit HtmlSelect
HtmlTextArea BulletedList Button
Calendar CheckBox Table
ChildTable WizardChildTable DataControlButton
ImageButton DataControlImageButton LinkButton
DataControlLinkButton DataControlPagerLinkButton DataGridLinkButton
DetailsView DropDownList FormView
GridView HiddenField ImageMap
LayoutTable ListBox Menu
PagerTable RadioButton RadioButtonList
TextBox TreeView WizardDefaultInnerTable
CatalogZone ConnectionsZone EditorZone
WebPartZone ZoneButton ZoneLinkButton


안타깝게도 DataList나 Repeater 같은 컨트롤은 이러한 호환성 문제가 있는듯 합니다. 단순히 Event Validation 설정을 끄는것으로 문제를 해결할 수도 있겠지만 좀 더 완전한 방법을 찾아야 했기 때문에 다양한 도구와 기법을 이용해서 문제를 추적해본 결과 원인을 알아낼 수 있었습니다.


포스트백 이벤트 검증 기능을 지원하지 않는 컨트롤 자체 및 해당 컨트롤 아래에 배치된 자식 컨트롤의 경우 UniqueID, ClientID 값 자체가 ID 프로퍼티의 값과 동일하게 바뀌면서 고유한 식별자가 누락되는 문제점이 있습니다. Render 이벤트를 Overriding해서 ClientScriptManager의 RegisterForEventValidation 메서드를 호출해서 직접 등록을 했다고 할지라도 검사가 실패하게 되는 가장 큰 원인입니다.


문제를 알아내기 위하여 조사하는 과정 중에 혹시 __EVENTVALIDATION 항목의 직렬화 처리에 버그가 있는 것은 아닌지 조사도 해보았지만 잘 작동하고 있었습니다. 이 부분에 대해서는 __VIEWSTATE 항목과 마찬가지로 안심하셔도 될 듯 하네요.


이 문제를 해결하기 위한 방법은 좀 더 시간을 내서 고민해 봐야 할 듯 합니다. 지금 택할 수 있는 방법은 이벤트 핸들러를 통하여 제공되는 sender 파라미터를 리플렉션으로 추적하는 방법이었으며 다행히 의도대로 잘 동작하고 있습니다.


1. 정상적으로 이벤트 핸들러를 호출하였다면 sender는 null 참조가 아닌 Control 객체입니다. 변환에 실패하면 데이터 바인딩을 추적할 수 없으므로 함수 실행을 종료해야 합니다.


2. 변환된 컨트롤을 통하여 Parent 프로퍼티로 가져올 수 있는 객체가 IDataItemContainer 인터페이스를 구현하고 있는지 확인합니다. 변환에 실패하면 데이터 바인딩을 추적할 수 없으므로 함수 실행을 종료해야 합니다.


3. 변환된 컨트롤 자체가 버튼 계열 컨트롤이고 이벤트 버블링을 위하여 CommandName이나 CommandArgument를 지정하였다면 IButtonControl 인터페이스를 구현하고 있을 가능성이 크므로 IButtonControl 인터페이스로 형 변환을 하거나 실제 컨트롤 형식으로 형 변환을 해둡니다.


4. IButtonControl 인터페이스로부터 얻을 수 있는 CommandName, CommandArgument와 함께 IDataItemContainer로 항목의 index를 조사할 수 있으므로, 원래 데이터 바인딩 항목이 속해있던 템플릿 컨트롤을 찾아서 프로그래밍하면 원하는 목적을 달성할 수 있습니다.

댓글 남기기