Wrong parameter being passed from an ObjectDataSource's SelectMethod

D

Damon

Help! Need this fixed ASAP.

I have a GridView/DetailsView master/details form set up, with both
bound to separate ObjectDataSource objects. Both the GridView and the
DetailsView have a DataKeyNames parameter of "UserCompany,
BillableCompany". The DetailsView has control parameters for its
select method pointing to these two keys on the GridView. But the
select method function receives two copies of the UserCompany field!
The BillableCompany field never gets passed correctly.

What gives?

A simplified version of my ASP.NET code follows:

<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="EditBillableCompanies.aspx.vb"
Inherits="EditBillableCompanies" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Billable Companies</title>
</head>
<body style="font-size: 12pt">
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<asp:GridView ID="GridView1"
AutoGenerateColumns="False"
DataSourceID="MasterSource1"
DataKeyNames="UserCompany, BillableCompany"
runat="server">
<Columns>
<asp:CommandField ShowSelectButton="True"
/>
<asp:BoundField DataField="UserCompany"
HeaderText="User Company" />
<asp:BoundField DataField="BillableCompany"
HeaderText="Billable Company" />
</Columns>
</asp:GridView>
</td>
<td valign="top">
<asp:DetailsView ID="DetailsView1"
AutoGenerateRows="False"
DataSourceID="DetailsSource1"
DataKeyNames="UserCompany, BillableCompany"
EmptyDataText="No records."
runat="server">
<Fields>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ContactName"
HeaderText="Contact Name"
SortExpression="ContactName" />
<asp:BoundField DataField="ContactPhone"
HeaderText="Contact Phone"
SortExpression="ContactPhone" />
<asp:BoundField DataField="ContactEmail"
HeaderText="Contact Email"
SortExpression="ContactEmail" />
</Fields>
</asp:DetailsView>
</td>
</tr>
</table>
&nbsp;
&nbsp;
<asp:ObjectDataSource
ID="DetailsSource1"
TypeName="BillableCompaniesDetailView"
ConflictDetection="CompareAllValues"
SelectMethod="SelectBillableCompanies"
UpdateMethod="UpdateBillableCompanies"
runat="server">
<SelectParameters>
<asp:ControlParameter ControlID="GridView1"
Name="UserCompany"
PropertyName="SelectedValue"
Type="String" />
<asp:ControlParameter ControlID="GridView1"
Name="BillableCompany"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
<UpdateParameters>
...
</UpdateParameters>
</asp:ObjectDataSource>
<asp:ObjectDataSource
ID="MasterSource1"
TypeName="BillableCompaniesMasterView"
SelectMethod="SelectBillableCompanies"
runat="server">
</asp:ObjectDataSource>
</div>
</form>
</body>
</html>

The BillableCompaniesDetailView class includes the following function:

Public Function SelectBillableCompanies(ByVal UserCompany As String, _
ByVal BillableCompany As String) As MySqlDataReader

BillableCompany is always the same value as UserCompany, and when this
function is called, they are both from the UserCompany field of my
MySql database.

Help!

Damon
 
W

Wiktor Zychla [C# MVP]

I have a GridView/DetailsView master/details form set up, with both
bound to separate ObjectDataSource objects. Both the GridView and the
DetailsView have a DataKeyNames parameter of "UserCompany,
BillableCompany". The DetailsView has control parameters for its
select method pointing to these two keys on the GridView. But the
select method function receives two copies of the UserCompany field!
The BillableCompany field never gets passed correctly.

I hope that a simple solution exists for your problem and someone will
provide you with it but having similar problems with parameters that should
be passed to Insert/Update methods, I would suggest you to write a handler
for ObjectDataSource's Selecting event. inside the event you get the
collection of parameters that are passed to the Select method. however, you
are free to modify this collection. In particular, you can clear the whole
collection and put inside any names/values you wish. I use this techique
constantly for inserting/updating so I have one generic inserting/updating
method in the data source type and I am able to call this method from any
context that needs to insert/modify data no matter how many attributes are
actually modified by the user interface.

regards,
Wiktor Zychla
 
D

Damon

Well, I finally found a solution. After much laborious web searching,
I found that using a ControlParameter to point back to the GridView
with the selected value pointed to by the PropertyName field only works
if there is only one ControlParameter! The selected value will always
be from the first column of the GridView.

In order to address this, we need to use an event handler to catch the
select event of the GridView object and then manipulate the parameters
that are passed to the ObjectDataSource control for the DetailsView
object. An event handler for the DetailsView or the ObjectDataSource
control won't work (and I found this out the hard way!) because the
parameter values are modified by the select event handler for the
GridView afterwards.

Put the following event handler at the top of the asp page, right after
the Page and Doctype definitions, as follows:

<script runat="Server">
Sub GridView1_Select(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles GridView1.SelectedIndexChanged
Dim gv As GridView
gv = sender
If Not gv.SelectedRow() Is Nothing Then

DetailsSource1.SelectParameters("UserCompany").DefaultValue() =
gv.SelectedRow().Cells.Item(1).Text()

DetailsSource1.SelectParameters("BillableCompany").DefaultValue() =
gv.SelectedRow().Cells.Item(2).Text()
End If
End Sub
</script>

Then, tell the GridView object about this event handler:

<asp:GridView ID="GridView1"
AutoGenerateColumns="False"
DataSourceID="MasterSource1"
DataKeyNames="UserCompany, BillableCompany"
OnSelectedIndexChanged="GridView1_Select" <--
Add this
runat="server">
<Columns>
<asp:CommandField ShowSelectButton="True"
/>
<asp:BoundField DataField="UserCompany"
HeaderText="User Company" />
<asp:BoundField DataField="BillableCompany"
HeaderText="Billable Company" />
</Columns>
</asp:GridView>

Finally, make sure that the parameters for the ObjectDataSource object
associated with the DetailsView are NOT ControlParameters, like so:

<asp:ObjectDataSource
ID="DetailsSource1"
TypeName="BillableCompaniesDetailView"
DataObjectTypeName="BillableCompaniesType"
ConflictDetection="CompareAllValues"
OldValuesParameterFormatString="original_{0}"
SelectMethod="SelectBillableCompanies"
UpdateMethod="UpdateBillableCompanies"
runat="server">
<SelectParameters>
<asp:parameter <-- not a ControlParameter!
Name="UserCompany"
Type="String" />
<asp:parameter <-- not a ControlParameter!
Name="BillableCompany"
Type="String" />
</SelectParameters>
<UpdateParameters>
...
</UpdateParameters>
</asp:ObjectDataSource>

And that's it. Now the parameter values will be correct.

Damon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,233
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top