views:

804

answers:

3

Greetings!

I'm creating a User Control that will display data in a GridView control. We are using n-tier architecture and the data in question is retrieved from our database and returned to us as a ReadOnlyCollection. OurNewObject is a class containing several properties and an empty constructor that takes no parameters - it's in the following namespace: Acme.ObjectModel.

In the user control, I have the following:

<asp:GridView ID="ourGrid" runat="server" DataSourceID="ourDataSource">
    <columns>
    <asp:BoundField DataField="Name" HeaderText="Full Name" />
    <asp:BoundField DataField="Gender" HeaderText="Gender" />
    <asp:BoundField DataField="BirthYear" HeaderText="Year of Birth" />
    <asp:BoundField DataField="JoinDate" HeaderText="Date Joined" />
  </columns>
</asp:GridView>
<asp:ObjectDataSource ID="ourDataSource" runat="server" SelectMethod="GetTopUsers" TypeName="Acme.Model.OurNewObject">
</asp:ObjectDataSource>

In the User Control's code behind, I have the following public method:

public ReadOnlyCollection<OurNewObject> GetTopUsers()
{
    return (OurDataProxy.GetJustTheTopUsers());
}

When I place the User Control on a Web form and run it, I get the following message:

ObjectDataSource 'ourDataSource' could not find a non-generic method 'GetTopUsers' that has no parameters.

So my questions are:

  1. Am I using the ObjectDataSource incorrectly?
  2. Is there a more proper way to use the ObjectDataSource in this situation?

Thanks.

A: 

I believe the issue is missing two attributes.

First on your GetTopUsers() Method add this attribute

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, true)]

Then on the actual OurNewObject class add this attribute

[System.ComponentModel.DataObject]
Mitchel Sellers
The problem is that OurNewObject is defined in another assembly, so I can't add that attribute to it.
Bullines
You will then have to bind to it in a different manner, just get the collection and set the datasource and then call databind from the codebehind.
Mitchel Sellers
A: 

Try adding the DataKeyNames (add the primary key) attribute to the GridView and see if that works?

IrishChieftain
+2  A: 

Normally, you would create a separate object that contains your data access method(s), rather than putting the methods in the code-behind. The separate object can be an instance or static, but the object itself must have a parameterless constructor (or no constructor at all).

Also, the TypeName property on the ObjectDataSource should reference the typename of the above-mentioned separate object. Example:

public class SampleDataObject
{
  public ICollection<OurNewObject> GetTopUsers()
  {
    //[...]
  }
}

The attributes mentioned above: [System.ComponentModel.DataObject(true)] at the class level, and [System.ComponentModel.DataObjectMethod(DataObjectMethodType.Select)] at the getter method are not required, but will aid in design-time support by filtering out other types when looking for classes to hook yer ObjectDataSource up to.

Jeff Woodman