I’m taking a break from posting iPhone development code this week. At work I was implementing a cascading drop down list and ran into a few issues. You figure you could watch the tutorials on asp.net’s website and everything would work. Wrong! I am using the dropdownlist control in a form view on the aspx page with binding, so anytime you would submit the form it would spit out an “Invalid postback or callback argument” error. Some suggestions posted on various web pages, blogs, and message boards say to disable EventValidation on the page. What? This is WRONG, WRONG, WRONG! This will bypass all the security was built in to protect against injection attacks. As one of my college professors would always say: “bad dog!”
What you really want to do is register all of the possible values for each dropdownlist. Where can you do this? You have to overriding the Render sub procedure in the code behind file. Here is sample code to fix this issue:
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
If (Me.FormView1.CurrentMode = DetailsViewMode.Insert) Then
Dim ddl1 As DropDownList = CType(Me.FormView1.FindControl("ddlDepartment"), DropDownList)
Dim ddl2 As DropDownList = CType(Me.FormView1.FindControl("ddlEquipment"), DropDownList)
'Load the data from the Departments table into the dropdownlist control for validation
Dim departmentsAdapter As New DepartmentsTableAdapter
For Each row As DataRow In departmentsAdapter.GetDepartments
Page.ClientScript.RegisterForEventValidation(ddl1.UniqueID, _
Trim(row("DepartmentName").ToString()))
Next
'Load the data from the Equipment table into the dropdownlist control for validation
Dim equipmentAdapter As New EquipmentTableAdapter
For Each row As DataRow In equipmentAdapter.GetAllEquipment
Page.ClientScript.RegisterForEventValidation(ddl2.UniqueID, _
Trim(row("EquipmentName").ToString()))
Next
End If
MyBase.Render(writer)
End Sub
I also needed to add required field validators to the drop down lists. This will make sure the user actually selects a value. To do this was pretty simple, you just need to set the InitialValue equal to “”. See the sample code below:
<cc1:CascadingDropDown ID="CascadingDropDown1"
runat="server"
Category="Department"
LoadingText="Loading..."
PromptText="Select a Department"
TargetControlID="ddlDepartment"
ServiceMethod="GetDepartments"
ServicePath="EquipmentService.asmx">
</cc1:CascadingDropDown>
<cc1:CascadingDropDown ID="CascadingDropDown2"
runat="server"
Category="Equipment"
LoadingText="Loading..."
PromptText="Select Equipment"
ParentControlID="ddlDepartment"
TargetControlID="ddlEquipment"
ServiceMethod="GetEquipment"
ServicePath="EquipmentService.asmx">
</cc1:CascadingDropDown>
<asp:DropDownList ID="ddlDepartment" runat="server"
SelectedValue='<%# Bind("Department") %>'>
</asp:DropDownList>
<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
ControlToValidate="ddlDepartment"
InitialValue="" ErrorMessage="Department is required"
Display="Dynamic" >*</asp:RequiredFieldValidator>
<asp:DropDownList ID="ddlEquipment" runat="server" SelectedValue='<%# Bind("Equipment") %>'>
</asp:DropDownList>
<asp:RequiredFieldValidator id="RequiredFieldValidator2" runat="server"
ControlToValidate="ddlEquipment"
InitialValue="" ErrorMessage="Department is required"
Display="Dynamic" >*</asp:RequiredFieldValidator>
That’s it! You now have cascading drop down lists that are fully functioning in a data bound formview.

