EventValidation is a nice ASP.NET integrated security feature: it ensures the page was not tweaked between postbacks.
But there may be times when we need to update, say, the items within a drop down list on the client.
<asp:DropDownList id="MyDropDownList" runat="server" />
<asp:button ID="SubmitButton" runat="server" text="Submit" />
What if we try to update that drop down list with javascript?
var newItem = document.createElement("Option");
newItem.text = "Item Text";
newItem.value = "Item Value";
var myDropDownList = document.getElementById('<%= MyDropDownList.ClientID %>');
myDropDownList.options.add(newItem, newItem.length + 1);
An exception will be thrown upon postback, because MyDropDownList possible values were changed from its initial rendering.
We could disable EventValidation for the whole application in web.config file
<pages enableEventValidation="false">
or for the current page
<%@ Page Language="C#" EnableEventValidation="false" ... %>
This would expose our application/page to other tweakings...
So why not use AJAX? We can incapsulate the drop down list into an UpdatePanel, and handle drop down items update within asynchronous postbacks.
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server" ID="MyUpdatePanel">
<ContentTemplate>
<asp:DropDownList id="MyDropDownList" runat="server" />
<asp:button ID="SubmitButton" runat="server" text="Submit" />
</ContentTemplate>
</asp:UpdatePanel>
An update request can be invoked by javascript using the __doPostBack() function
__doPostBack('MyUpdatePanel', 'UPDATE');document.getElementById('__EVENTARGUMENT').value = "";
And handled on the server within the Load event
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
if(Request.Form["__EVENTARGUMENT"].StartsWith("UPDATE"))
{
MyDropDownList.Items.Add(new ListItem("Item Text", "Item Value"));
}
}
}
This will perform an asynchronous update when the page is displayed. A new item is added on the server side and the drop down list is re-rendered within the update panel.We are creating a new ListItem with static values here. With a little more change in this code, we can pass more informations within the event argument
__doPostBack('MyUpdatePanel', 'UPDATE_Custom Text_Custom Value');
and parse it on the server.
string[] values = Request.Form["__EVENTARGUMENT"].Split('_');
MyDropDownList.Items.Add(new ListItem(values[1], values[2]));