Binding ObjectDataSource controls to Custom Methods

The new ASP.NET 2 data controls, like the SqlDataSource and the AccessDataSource grealty simplify data access in your Web Applications. However, they have one major drawback: they flood your pages with Sql statements. Not so with the ObjectDataSource, that enables you to bind to the results of a standard method in your Business Logic Layer. The ObjectDataSource can in turn be bound to a data aware control, like the new GridView or DetailsView controls

There are a few ways to bind the ObjectDataSource control to your method. The methods you can use depend on the design of your BLL class and method.

Method 1 - The Default Constructor

If your BLL class has a default, parameterless constructor, you can simply assign the method like this:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
      SelectMethod="MySelectMethod" 
      TypeName="MyType">
</asp:ObjectDataSource>					

As you can see, you have to define the TypeName (the name of the class in your Business Layer that contains the method you want to call) and the actual name of the method for the SelectMethod property. Before that method is called, the .NET run-time will automatically create an instance of MyType by calling its default constructor (that has no parameters).

The method signature can look as simple as this:

public DataSet MySelectMethod()
{

}  

Method 2 - Static Methods

The next method uses the exact same markup as the first method, but this time the method in the Business Layer is static:

public static DataSet MySelectMethod()
{

}  


With the static method, there is no longer the need to have a default, parameter less constructor on the MyType class. If the class only contains static methods, you can even hide the constructor alltogether by marking it as private.

Method 3 - Using ObjectCreating

The next, and final method I am discussing here, is using the ObjectCreating event. This event is fired by the ObjectDataSource control just before it tries to call your method. Inside this event, you can create an instance of your custom Business class, passing it any type of information it may need to receive in its constructor. Then you assign your custom object to the ObjectInstance property of the ObjectDataSourceEventArgs parameter. The following example shows a simple example of this:

protected void ObjectDataSource1_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
  MyType myType = new MyType(1, "SomeValue", SomeCustomObject);
  e.ObjectInstance = myType;
}  

Once this event is done, your custom object myType is then used as the source for the MySelectMethod that is used to bind the ObjectDataSource control. So, under the hood myType.MySelectMethod() is called on your business object to get the data in the ObjectDataSource control.


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Wednesday, July 12, 2006 8:58:52 PM shane said:
very helpful! I wasn't even thinking of using the onobjectcreating functionality to solve my parameterless constructor roadblock -

thanks!
On Monday, August 21, 2006 8:26:09 AM abdullah said:
Very Good, really having a fast scan over this artical have solved my probelm, which I spent about 2 hours to solved before finding this Nice Article.
On Thursday, March 01, 2007 7:28:21 PM Ting said:
I used the on objectCreating event to set param for my constructor. How do I rebind it with new param when the argument changed?
On Thursday, March 01, 2007 8:39:50 PM Imar Spaanjaars said:
Hi Ting,

You can call DataBind() on the ODS or on the underlying data control.

Imar
On Wednesday, March 14, 2007 3:56:27 PM Lawrence said:
Hi,
First of all thx for the nice article.
I still experienced some problems:

When the page loads for the first time, the Objectdatasource is trying to call my select method.
But I added some controls to the selectparameters.
So when the page start those parameters are empty and I get a "scalar @vehicleId" error. This because the vehicle Id is null when the page first loads.
How can I tell the ObjectDataSource to only call the select statement when all parameters (data from the controls) are set and NOT on _ObjectCreating?

thx 4 the fast reply
On Wednesday, March 14, 2007 7:50:09 PM Imar Spaanjaars said:
Hi Lawrence,

For some reason the ObjectDataSoure lacks the CancelSelectOnNullParameter property that cancels the Select operation when one or more parameters are null. The SqlDataSource has that property which can be very convenient.

However, you can work around it by adding some code in the Selecting event of the ODS, that fires right before the control is about to get its data. Inside that event, you can check the parameter values and if one or more of them are null, then set:

e.Cancel = true;

This cancels the Select operation of the ODS.

Cheers,

Imar
On Monday, March 19, 2007 4:01:52 PM Ting said:
Great article. Very helpful! Thank you so much!
On Friday, April 25, 2008 4:12:34 PM Jatin Mehta said:
Hi,

I want to bind a ObjectDataSource at runtime with my gried view control. How can i do that?
On Friday, April 25, 2008 4:21:19 PM Imar Spaanjaars said:
Hi Jatin,

You could probably create one programmatically and assign it. But why would you want to do that?

Imar
On Friday, April 25, 2008 5:08:16 PM Jatin Mehta said:
        ObjectDataSource objODSource = new ObjectDataSource();
        objODSource.TypeName = "clsCustomer";
        objODSource.SelectMethod = "RetrieveAllCustomer";
        objODSource.SelectParameters.Add("isAllCustomerRequired", "true");
        objODSource.SelectParameters.Add("strCommaSepratedCustomerIDs", "");
        objODSource.Select();
        grdCustomer.DataSourceID = "objODSource";

Where RetrreiveAllCustomer will return Customer Object with contains two propery named "Name" and ID

Can you tell me what is problem?
On Friday, April 25, 2008 5:21:02 PM Imar Spaanjaars said:
Hi Jatin,

The problem is that you are not saying what the problem is. All you do is post code. Does it work? If not, what are you expecting it to do and what does it actually do? Do you get an error? If so, what error?

I think you're better off posting this on p2p.wrox.com as it's too off-topic to answer here for me. If you do post there, be sure to provide lots of information.

Imar
On Saturday, May 03, 2008 9:17:14 AM Nirav said:
Hi,
I am new to use the ObjectDataSource,
I have similar question as Jatin has posted with the code.
I dont know what he is trying to ask, but in my scenario its similar code giving error:

"ObjectDataSource 'gDS' could not find a non-generic method 'GetReportData' that has parameters: _EmpName "

Here is the code:

public class empDataProvider{
public DataView GetReportData(string _EmpName){
//code to get DataView as per _EmpName
}
}


//in other class within same namespace

ObjectDataSource gDS = new ObjectDataSource();
gDS.TypeName = this.GetType().FullName + "," + this.GetType().Assembly.FullName;
gDS.SelectParameters.Add("_EmpName", TypeCode.String, "Mr.Xyz");
gDS.SelectMethod = "GetReportData"

Can you explain whats the reason for this error

I just want to pass _EmpName as select parameter in GetReportData method, so i can generate the dataview specific to that employee
On Saturday, May 03, 2008 9:39:07 AM Imar Spaanjaars said:
Hi Nirav,

You're better off posting this on p2p.wrox.com as it's too off-topic to answer here for me. If you do post there, be sure to provide lots of information.

Imar
On Monday, May 19, 2008 9:10:17 PM Vladimir Kelman said:
It looks like that having static BLL GetItem() and GetList() methods (which return business object and collection of business objects correspondingly) allow to *display* data without adding parameterless constructor and handling any events.
But when I try to update (save updated) data it raises "No parameterless constructor defined" error. Does ObjectDataSource tries to create an object again just before updating it (calling Update/Insert) method?
On Tuesday, May 20, 2008 6:25:39 AM Imar Spaanjaars said:
Hi Vladimir,

Please realize this is my personal blog, and not a public forum. These kind of questions are much better suited in a forum like http://p2p.wrox.com.

That said: yes, your BO needs a parameterless constructor. The run-time needs to recreate the object after a postback and doesn't know how to do that other than creating an instance and using reflection to set the relevant properties.

Imar
On Thursday, January 22, 2009 11:29:36 AM Ranijt said:
I'm using ObjectDataSoure to bind data to dropdownmenu.It bind data to dropdpown menu every time page is post back,How can i prevent it , so that it bind  drop down only when page loaded first time not at every post back
On Thursday, January 22, 2009 12:06:48 PM Imar Spaanjaars said:
Hi Ranijt,

You can call

e.Cancel = true;

in the Selecting event if you don't want to select the data.

Cheers,

Imar

On Wednesday, August 19, 2009 6:03:12 PM isaac mihaeli said:
This sample is very refreshing and the ObjecrDataSource is great when it works. However, in my case I get an error message stating that; “ObjectDataSource could not find a non-generic method,” that has several parameters. I am trying to understand the message and searched on several sites without any results.
On Wednesday, August 19, 2009 6:26:49 PM Imar Spaanjaars said:
Hi isaac,

That message suggests that you fewer or more parameters defined in your SelectParameters element than your object method expects.

If you post the code in a relevant ASP.NET forum at http://p2p.wrox.com/index.php?referrerid=385 and send me the link to the post, I'll take a look at it.

Cheers,

Imar
On Wednesday, September 09, 2009 8:12:00 AM omar said:
hi imar
how can I achive the following for deleted items / messaged page

I want for ever message ; 2 buttons delete and undelete  both only change a flag in the data base
I have simple gridview binded to object data source  
I have normal TemplateField having link button CommandName = “Delete”
In Ods I defined  Delete Method =”Delete” and it’s ok .

For un delete I want to do the same , how ?

For the link button  I want commandName =”UnDelete”
And in the ods “UndeleteMethod” = “UnDelete”

Can I do achieve this
Or how to solve the problem
On Wednesday, September 09, 2009 10:23:27 AM Imar Spaanjaars said:
Hi omar,

That's a bit too much, and a bit too much off-topic to answer here. May I suggest you post this in one of the ASP.NET categories of the forum run by Wrox: http://p2p.wrox.com/index.php?referrerid=385

Cheers,

Imar
On Thursday, September 23, 2010 12:56:56 PM Ben said:
Excellent!  I've been tasked on fixing some issues in a .NET cms and hit a roadblock on this one.  I didn't know about this and by creating an intermediary object and using method #3, problem solved.

Great stuff!
On Friday, June 17, 2011 2:26:41 PM Black said:
Hi Imar,
I am getting this error message "Typename property of ObjectDataSource could not be found"

Can you please help me with this matter. I've declared the class name as Typename so what is the problem??

Thanks
Black
On Sunday, June 19, 2011 4:21:39 AM Imar Spaanjaars said:
Hi Black,

Did you also include the class's namespace? E.g. Name.Space.ClassName?

Imar
On Monday, June 20, 2011 12:20:43 PM Black said:
I think I don't have a namespace (but i'm not sure, because I'm still learing asp and the concept of namespace isn't clear to me.) Is there any way to find out whether I'm using namespace? (This project was created by someone else)

FYI
I've searched Bin folder for "assembly prefix" but didn't get a name that make sense (all I got were like: cssfriendly.dll, ajaxExtender.dll, exit.dll)

and Thanks for your reply
On Wednesday, June 22, 2011 2:50:58 AM Imar Spaanjaars said:
Hi Black,

You define a namespace in your code file as a wrapper around a class. E.g.:

namespace MyNamespace
{
  class MyClass
  {

  }
}

When using VB, you can also have a root namespace which you can set on the project's Properties dialog.

Cheers,

Imar
On Friday, July 01, 2011 11:06:32 AM Black said:
Sorry for the late reply but I wanted to see if it worked first. And it didn't work :(

I wrapped the class with a Namespace "Address" and in the ObjDataSrc's TypeName, I typed "Address.myClassName". But as I said b4 it didn't work. Do you have any suggestions???

I really appreciate your help :)
On Friday, July 01, 2011 2:15:33 PM Black said:
Hi Imar,

Finally my problem was solved. I used a small piece of code that I found here:
http://kannanmk.blogspot.com/2010/09/type-name-for-object-datasource-in.html

Thanks for your help

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.