DoughBoy 04-25-2007, 04:31 PM First off, I have a very simple page with some drop down list boxes, and a few text boxes. With AJAX, I have these boxes populated based on a user's selection. Upon clicking the submit button, the page throws a pretty ugly error.
"Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
After doing some research on the topic, it seems the only solution to this is to have enableEventValidation="false"... Unwillingly I typed that into the page header. And needless to say, this error isn't raised anymore. BUT, the main topic for this thread......
I can't retrieve the values located within the drop down lists, or text boxes. I am not specifying anything for default values, nothing is listed in the Page Load function, I am purely calling 'TextBox1.Text' in the SubmitBtn_Click function, and the value is nothing.
I'm completely lost on how to solve this issue. After googling and searching this site for answers, I keep running into dead ends.
Any thoughts or opinions??
MKoslof 04-25-2007, 05:37 PM Yes, unfortunately this is a common problem :). You don't need to use the enableEventvalidation option to get around this problem. What you can do is within the ACTUAL callback of the ClientCallback you can register for event validation for the given control and pass in the value (you trap the return from your AJAX call).
Now without disabling EventValidation for the entire page you get around nasty ASP.net errors. I don't have this code handy right now, but if you want to know how to accomplish this let me know and I will dig it up, its on the work computer :).
With that being said you still will not have the value within the drop down list until the server POST BACKS and re-draws the control. This is how I have gotten around this issue in the past:
Create a hidden field on your form. Through java script assign the value of this hidden control to your combo box value. Now if you need to reference the "new" or AJAX populated value you refer to your hidden input field. This works great and it allows you to "know" the new values before the server actually post backs and redraws itself.
Its not the most elegant solution, but it will get you past this current hurdle :)
DoughBoy 04-25-2007, 09:20 PM MKoslof, once again you have saved me from a trip to get a hair transplant! :)
Yes, having values from DropDownLists sent to hidden fields isn't the prettiest thing, but if it'll work... Then thats how it'll be. :)
Sad to say, you did lose me with sending my trapped AJAX call to be registered as EventValidation on the ClientCallback. (I hope I summed that correctly).
I apologize for not seeing this clearly. But, AJAX calls an aspx page which will be returned to it, an XML formatted text string. What exactly is being trapped and how do I register it? Again, sorry for my ignorance with this.
Thanks for all your help.
MKoslof 04-27-2007, 01:55 PM OK, I assume you are implementing ICallbackEventHandler correct? Basically this is what I was getting at.
When you implement ICallbackHandler you override two core methods: RaiseCallBackEvent(string argument) and GetCallBackResult(). If you have a class level variable that stores the string result from RaiseCallBackEvent() you can register THAT value within the TARGET control within the GetCallBackEvent(). This will tell ASP.net that the newly added value is "safe" and "validated" and you don't have to turn off event validation for the entire page.
Let's say you have a '| |' delimiter for your string results. Lets assume the class level variable name is Dim result as string, etc
1) In RaiseCallBackEvent() assign your class level variable to the call back result:
result = myStringBuilder.ToString() (here we are assuming you used a string builder to concat some values, etc)
2) In GetCallBackEvent():
Now pass the value to the RegisterForEventValidation() event, you can do this on the fly:
'***parse out the return value result, however you have constructed it, etc
Dim toValidate as string
toValidate = results.Split("| |".ToCharArray())[0];
Page.ClientScript.RegisterForEventValidation(theControl.UniqueID, toValidate)
As noted before this will not solve the control re-rendering issue. You still need to use the hidden field approach or another method to get around that :). But this will allow you to NOT disable event validation for the entire page, which is something you want to avoid if possible.
Let me know if you have any other questions.
DoughBoy 04-27-2007, 09:34 PM MKoslof,
Thanks for your detailed explaination. Sadly, at first glance this topic flew over my head. I'm going to need to spend some time digesting this and trying to tie it into my application. If I have any more questions I'll post them.
Thanks again for your help. :)
MKoslof 04-28-2007, 12:28 PM OK, sorry, I assumed you already had a control which implements the ICallBackHandler and you simply needed to know how to hook in the runtime event validation code.
Do a search of Google for ICallBackHandler and its overriden events in most implementation RaiseCallBackEvent() and GetCallBackResult(). Then I think this will make more sense to you.
At a high level:
RaiseCallBackEvent will construct the AJAX call back string which is returned to the client level javascript or browser.
GetCallBackEvent() is the tunnel that basically "sends back" what you constructed in the RaiseCallBackEvent. Within GetCallBackEvent you can review the string value(s) you created and register the control which is going to be updated with event validation via the RegisterForEventValidation() method - - passing that controls unique id and the values. Again, you will need a private class level string which holds the value(s) since you need to construct it within the RaiseCallBackEvent() method and evaluate it/parse it within the GetCallBackEvent method so the value can be assigned to the target control, etc.
|