Collaboration between Client Callbacks and Event Validation

Unfortunately I was not able to cover all details on client callbacks and event validation during my talk at the Developer Days. I did find out some interesting things on the combination. Let me tell you about it.


When a callback is made from a ASP.NET 2.0 web page or control that supports Client Callbacks, the posted data looks something like this:


__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPAh4Hb25jbGljawUgR2V0SGVsbG9aXb3JabdcsxMiwgJ2w1&
__CALLBACKID=__Page&__CALLBACKPARAM=12&
__EVENTVALIDATION=%2FwEWAwL%2BraDpAgL7%2B4SRCAKM54rGBpFe3rPMr2H7QsP2vv4x4ojYDdL2


There might be other values from controls, but notice the __EVENTVALIDATION field. It contains encoded and MACed data that represents the events and their possible arguments that were registered for event validation. Controls that have not registered their events are not allowed to fire events in ASP.NET 2.0. All controls in the .NET Framework register their events and arguments by default, if the controls are populated server-side.


Because it is very likely that the data that is sent back from a callback will be used to update the UI and the controls in it, you do get a chance to register extra events for validation. Previously I mentioned that you should put calls to RegisterForEventValidation inside the override of the Render method. But, … you can also register inside the GetCallbackResult method. The fragment below shows part of a possible implementation. The result of the callback is a pipe ( | ) delimited list of items from a filtered DataSet.


publicstring GetCallbackResult()
{
  …
  DataView
view = data.Tables[0].DefaultView;
  view.RowFilter = String.Format(“Region='{0}'”
, argument);
  StringBuilder builder = newStringBuilder
();
  int
index = 0;
  foreach (DataRowView row in
view)
  {
    builder.Append(row[“CustomerName”] + “|”
);
    ClientScript.RegisterForEventValidation(“ListBox1”,
      index.ToString());
    index++;
  }
  return
builder.ToString();
}


The page framework will take care of composing the new value of the event validation hidden field and will send it back as part of the result. That would look like this:


14|/wEWDgLh94y+AQCustomer1|Customer2|Customer3


where the format is Length|NewEventValidationDataResponse. The length represents the length of the string for the new event validation data. The new data replaces the original value of the __EVENTVALIDATION field. Upon a real postback the new event validation data will allow the controls to fire events (with arguments if applicable). Important note: you still cannot read the new values from the controls. You need to read them directly from the raw request using the indexer property on Request, such as Request[“ListBox1”]..


Anyway, this mechanism will allow you to



  1. dynamically add values to a control, such as as dropdownlist from callback data

  2. have the control fire an event (maybe an SelectedIndexChanged from an AutoPostback)

  3. make the ASP.NET runtime allow the event to be raised, because the event validation data has been updated as part of callback roundtrip

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s