This is the second part in a post on EventValidation in ASP.NET 2.0. In this post I will address the topic of event validation. This new feature becomes apparent when trying to use client callbacks in combination with new values for controls. If you are unfamiliar with the topic of client callbacks and the resulting exceptions that may occur, read the first part here.
The question to answer: why and what is the new feature in ASP.NET 2.0 for event validation? I’ll work towards the answer in steps.
Have you ever tried to manipulate the items in a dropdownlist, say by changing values and maybe adding additional items? I know I have, in a study of SQL injection attacks on ASP.NET web applications. As it turned out the values of the dropdownlist come from the viewstate instead of from the page. And the extra items in the dropdownlist are discarded because they do not appear in the viewstate. A very good thing indeed.
So, now you know were the exception originates from. Next question is: how do I play by the rules?
There is a way to disable the event validation mechanism. Just add the EnableEventValidation=”false” attribute to the page or control directive. Or, you can go for the <pages enableEventValidation=”false”> approach, to apply it to all pages at once. BUT, both methods will disable all validation of values of controls in the entire/all page(s) and opens up the security holes that were meant to be covered. In other words: you will need to validate your postback data yourself! It is similar to turning off ValidateRequest for the page and having to check for tags in the received input. Remember one of the main security rules: NEVER EVER trust user input. You should be on the safe side with that.
I hear you say: “So what’s with this RegisterForEventValidation method?” Well, normally, a control will register each of the values that it knows will be postable from the page. You do so at the time of rendering of the page. Here’s a fragment:
protected override void Render(HtmlTextWriter writer)
With this code in place you would be allowed to do a postback with the value “One” from ListBox1. There is a big downside to this approach when trying to use it in combination with client callbacks. Since the page only gets rendered once, you need to output ALL possible values at that time. This might not be feasible in a lot of situations, if any. This means you are kind of stuck with setting EnableEventValidation to false.
This will make the story complete: every control in ASP.NET 2.0 has to register all the events and arguments (if applicable) during the render phase. E.g., a button would typically call RegisterForEventValidation passing in itself as the control. No arguments necessary. Also, the control must be decorated with the SupportsEventValidationAttribute. During postback (to be precise: at RaisePostBackEvent) a control will call the ValidateEvent method and pass in the event argument it has received. This will check the administration of registered events and arguments to see if the postback data is allowed. If not, the terrible exception is thrown again.