CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

Custom bussiness objects for ASP.NET 2.0 object datasources

In ASP.NET 2.0 the gridview control is quite nice. By just setting some properties you can create a web application whose grid data can be edited by the end-user without the need to write all the plumbing code by hand. Which is quite a big step forward from 1.x. For this to work the gridview communciates with the data through a datasource. Most of these datasources, like the sqlDatasource, communicate directly with the database. Having them on your webform leads to monolithic webapps.

The way to layer an app is using an objectdatasource. In this article on the SDN site (you have to register to read the article. registration is free) I explored a way to use an ASP.NET dataset 2.0 style as bussinessobject. The story manages to separate the database access from the web-forms into two separate dll’s. Two layers, to turn these into tiers you need a RPC protocol for them to communicate over machine boundaries. For the SDN user group I’ll be doing a presentation on objectdatasources april 1st (no joke) to continue with this part of the story. Here some first shots at the subject.

The properties of the 2.0 dataset suggest a role for webservices; all those diagrams in team system suggest that as well. But browsing and googling around leave the subject quite misty. The “generate webmethods” option in the dataset will not make it into the final version. I havn’t seen beta2 yet, for the time being it will take some custom work. As a demo a webservice to wrap up functionality of the dataset. This webservice will expose some of the methods needed by the datasource. (The dataset used is described in the article.)

[WebServiceBinding(ConformanceClaims=WsiClaims.BP10,EmitConformanceClaims = true)]
public class Service : System.Web.Services.WebService {

    [WebMethod]
    public DataSetInvoices InvoiceList()
    {
        DataSetInvoices ds = new DataSetInvoices();
        InvoicesTableAdapter ta = new InvoicesTableAdapter();
        ta.FillList(ds);
        return ds;
    }

    [WebMethod]
    public void UpdateInvoice(System.DateTime InvoiceDate, int InvoiceNumber, int idCustomer, string Description, int Original_idInvoice)
    {
        InvoicesTableAdapter ta = new InvoicesTableAdapter();
        ta.Update(InvoiceDate, InvoiceNumber, idCustomer, Description, Original_idInvoice);
    }

}

The objectdatasource does not really work with a full dataset but with it’s tableadapaters. A dataset is fully SOAP-serializable, a tableadapater is not. You can try to make the webservice return a tableadapter, the result will be that all the VS2005 auto-magic will wrap the adapter up in a dataset nevertheless.

The original plan might have been to have the objectdatasource directly consume the webservice. For now we need a simple wrapper class which interacts with the webservice and exposes the functionality in the format the objectdatasource wants. The object datasource property builder lists classes available to provide the bussiness object.

It will look for classes decorated with the System.ComponentModel.DataObject attribute. The datasource looks for methods on the dataobject to retreive, update, insert or delete data. The property builder will look for methods decorated with the System.ComponentModel.DataObjectMethod attribute. The constructor of this attribute takes a member of the System.ComponentModel.DataObjectMethodType enumeration as parameter. There is a Select, Fill, Update, Insert and Delete member.

The objectdatasource looks for a matching method on the bussiness-object. Runtime it will look for a method whose parameter names match the parameters to be sent to the method. The names of the parameter have to match exactly, the casing of these names does not have to match. When Reflection finds no match an exception is thrown. The error message tell you what parameter names are expected. 

The type of the parameters is not checked. When invoking the method the objectdatasource will try to convert the parameters to the desired type, when this is not possible an execption is thrown. The callstack of the exception clearly shows the attempt Reflection has made.

In the gridview on the invoices the date, number, customer id and description columns can be edited. An object of this class can serve as a datasource:

[System.ComponentModel.DataObject]
public class BOwrapper
{

    [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
    public DataHost.DataSetInvoices.InvoicesDataTable InvoicesByName()
    {
        DataHost.Service ws = new DataHost.Service();
        DataHost.DataSetInvoices ds = ws.InvoiceList();
        return ds.Invoices;
    }

    [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Update)]
    public virtual int UpdateInvoice(DateTime InvoiceDate, int InvoiceNumber, int idCustomer, string Description, int Original_idInvoice)
    {
        DataHost.Service ws = new DataHost.Service();
        ws.UpdateInvoice(InvoiceDate, InvoiceNumber, idCustomer, Description, Original_idInvoice);
        return 1;
    }

}

The BOwrapper class exposes methods which the objectdatasource (and the gridview using that) understands. In the implementation of the mehods it does invoke the webservice. In this example it is a straightforward synchronous invocation. It’s up to you to attach any bell or horn you wish. Or implement another RPC protocol, instead of getting to the bussiness object via a webservice you might want to use remoting.

The result is that I have these layers

  • Webbrowser
  • Webform with objectdatasource
  • BOwrapper (can have its own dll)
  • Webservice
  • Database

There are several ways to slice these layers into several physical tiers. And I still have fully updatable data in the browser without having to code my own plumbing. That’s something I really want to leave behind in 1.1.

 


Published Mar 29 2005, 03:04 AM by pvanooijen
Filed under: ,

Comments

Peter's Gekko said:

Clicking the post button throws your blogpost into the outer world. Is it finished ? No, quite often...
# March 31, 2005 12:34 AM

Peter's Gekko said:

I had to miss the codeworse april fools joke. Spent the day doing my presentation on objectdatasources...
# April 6, 2005 6:19 AM

Peter's Gekko said:

In the North we were the first to have the MSDN/TechNet briefings. A couple of times a year MS organizes...
# October 12, 2005 7:25 AM

lbr said:

f disyatke i niipet !
# April 30, 2006 5:40 AM

pvanooijen said:

Right !
I'm sorry, don't speak Russian (?)
# May 10, 2006 6:08 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# December 20, 2007 8:57 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

This Blog

Syndication

News