Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

FormView Cascading DropDownList Binding problem 1

Status
Not open for further replies.

Qik3Coder

Programmer
Jan 4, 2006
1,487
US
Let me preface this with I didn't create this nightmare.

Page Setup:
There is a custom object data source which is used to "collect" all the bound field values, and place the values in SESSION, so that they can be put in an XML document on a downstream page.
There are separate Edit/Insert item templates, which are basically the same control.
There are SQL data sources within the templates to load drop downs.
I cannot change the architecture of the site as it is out of scope.
I have added a "empty" row to both drop downs for the initial page load.

Problem:
DropDown 1 works all the time with
SelectedValue='<%# Bind("sessionValue1") %>'

DropDown 2 works in the "Insert" mode with
SelectedItem='<%# Bind("sessionValue2") %>'

DropDown 2 throws a "ListItem Not Serializable" when I RETURN to the page and it's in EDIT mode, using SelectedItem

DropDown 2 throws a "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control." when I use SelectedValue instead of SelectedItem on postback, but not on initial load.

Thanks in advance,
Lodlaiden

You've got questions and source code. We want both!
 
The first thing I would do is take any binding code out of the markup. This is classic ASP type of coding. I am not sure why this would cause an error without more code posted. Set the selecteditem or selectedvalue from the codebehind, in the proper event and see if that eliminates any or all of the errors.
 
Also, what exactly is being stored in the session variables? Post the exact code that puts it there.
 
Code:
 <asp:FormView ID="FormView2" runat="server" DataSourceID="GenericBindObjectDataSource1"
            DefaultMode="Insert" OnItemInserting="FormView2_ItemInserting" OnInit="ItemsPage_Init"
            OnItemUpdating="FormView2_ItemUpdating" OnDataBound="FormView2_DataBound">

...

   <InsertItemTemplate>
                <div id="body">
                    <font color="red">*</font>Service Carrier:
                    <asp:DropDownList ID="ddlCarrier" runat="server" SelectedValue='<%# Bind("deviceCarrier") %>'
                        DataSourceID="sdsGetCarriers" DataTextField="Carrier" DataValueField="Carrier"
                        AutoPostBack="true" />
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="Carrier is required!"
                        Text="!" ValidationGroup="ValInsert" ControlToValidate="ddlCarrier" InitialValue="[Select Carrier]"></asp:RequiredFieldValidator>
                    <br />
                    <br />
                    <font color="red">*</font>Device Model:
                    <asp:DropDownList ID="ddlDevice" runat="server" SelectedValue='<%# Bind("deviceModel") %>'
                        DataSourceID="sdsGetDevices" DataTextField="DisplayText" DataValueField="SelectedValue"
                        AutoPostBack="true" AppendDataBoundItems="true" />
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ErrorMessage="Specific Device Model is required!"
                        Text="!" ValidationGroup="ValInsert" ControlToValidate="ddlDevice" InitialValue="[Select Mobile Device]"></asp:RequiredFieldValidator>
                    <br />
                    <br />

...
  <asp:SqlDataSource ID="sdsGetCarriers" runat="server" SelectCommand="prcGetSupportedHardwareCarriers"
                    ConnectionString="<%$ ConnectionStrings:XYZ %>" SelectCommandType="StoredProcedure">
                    <SelectParameters>
                        <asp:QueryStringParameter Name="DisplayGroup" QueryStringField="DisplayGroup" Type="String" />
                    </SelectParameters>
                </asp:SqlDataSource>
                <asp:SqlDataSource ID="sdsGetDevices" runat="server" SelectCommand="prcGetSupportedHardware"
                    ConnectionString="<%$ ConnectionStrings:XYZ%>" SelectCommandType="StoredProcedure">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="ddlCarrier" PropertyName="Text" Name="Carrier" Type="String" />
                        <asp:QueryStringParameter Name="DisplayGroup" QueryStringField="DisplayGroup" Type="String" />
                    </SelectParameters>
                </asp:SqlDataSource>

You've got questions and source code. We want both!
 
I need to see the code that places any values into the session variables.
 
It took me (way longer than it should have) to trace how this thing works.

It stores a custom dictionary object in session with name value pairs. It uses the X in bind("X") to determine the key. the value is whatever property it's attached to.

These values are then stored in a XML doc.

You've got questions and source code. We want both!
 
That's where it get's smelly.


This is at the bottom of every page:
Code:
 <gbd:GenericBindObjectDataSource ID="GenericBindObjectDataSource1" runat="server"
        SelectMethod="GetById" TypeName="X.Y.ItemCollection" RemoveEmptyFields="False"
        UpdateMethod="Update" InsertMethod="Insert">
        <SelectParameters>
            <asp:SessionParameter Name="id" SessionField="ID" Type="Object" />
        </SelectParameters>
    </gbd:GenericBindObjectDataSource>

Pertinent Guts of ItemCollection
Code:
            [System.ComponentModel.DataObjectMethodAttribute( System.ComponentModel.DataObjectMethodType.Insert, true )]
            public void Insert( OrderedDictionary fields )
            {
                if( !this.ItemHasRequiredFields( fields ) )
                {
                    throw new ArgumentException( "X." );
                }
                

                // Add any columns that don't already exist to the DataTable.
                //
                    foreach( DictionaryEntry de in fields )
                    {
                        if( !OrderItems.Columns.Contains( de.Key.ToString() ) )
                        {
                            OrderItems.Columns.Add( de.Key.ToString() );
                        }
                    }


                // Build a new row.
                //
                    DataRow row = this.BuildDataRowFromOrderedDictionary( fields );
                    this.InsertInternal( row );       
            }


            private void InsertInternal( DataRow row )
            {
                OrderItems.Rows.Add( row ); 
            }

[/code]


You've got questions and source code. We want both!
 
As your error states, ListItems are not serializable. So you have to trace through and find out what is trying to be stored in session when this error occurs.
 
Sorry it took this long to respond, production issue... (Who the heck puts a "/" in an AD Group Name!!!)

I had already traced it, but your comment prompted me to re-assess the code.

I added the following block after the foreach that iterates over the keys:
Code:
  //Save the Value of any ListItems that are stored
            int i = 0;
            while (i < fields.Count)
            {
                Object o = fields[i];
                if (o.GetType().FullName.ToString().ToLower().Contains("listitem"))
                    fields[i] = ((System.Web.UI.WebControls.ListItem)o).Value;
                i++;
            }

That was throwing an odd "Cannot serialized" list item on the page load, for the default item.

I changed the binding on the Edit Template to be SelectedValue instead of SelectedItem, which appears to have resolved my issue.
The insert template is still using SelectedItem.

Thanks for the help!
Lodlaiden

You've got questions and source code. We want both!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top