Click here to Skip to main content
Click here to Skip to main content

Complex Parameter Support for ObjectDataSource

By , 3 Feb 2009
 

Introduction - Object Data Sources with Object Parameters

The built in ASP .NET data-source model comes with support for a variety of parameter types, allowing us to feed our applications, used via data sources such as SqlDataSource, XmlDataSource and ObjectDataSource. The built in parameters however are fairly limited, in that you cannot build complex object structures, and must have all types resolve to a handful of simple types such as strings and integers. The closest ASP.NET allows us is that it automatically constructs some types when performing an Update or Delete, but there is no such support for Select's.

This example code shows how to build arbitrary objects as inputs to ObjectDataSources, by means of a custom parameter type, ObjectParameter. The ObjectParameter creates an instance of a specified type and then evaluates a set of parameter objects in order to populate the properties of the object. Visually this appears somewhat like:

ObjectParameter-Code

When translated to ASP.NET, this appears as:

        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
            SelectMethod="SearchEntities" 
            TypeName="CobaltSoftware.ExampleBusinessLayer.SomedataObject,
                 CobaltSoftware.ExampleBusinessLayer">
            <SelectParameters>
                <Cobalt:ObjectParameter Name="input"

                   TypeName="CobaltSoftware.ExampleBusinessLayer.SearchParametersEntity,
                   CobaltSoftware.ExampleBusinessLayer" > 
                    <Properties>
                        <asp:ControlParameter ControlID="TxtForename" name="Forename" />
                        <asp:ControlParameter ControlID="TxtSurname" name="Surname" />
                        <asp:ControlParameter ControlID="TxtAge" name="MinAge" />   
                    </Properties></properties />
                </Cobalt:ObjectParameter>
            </SelectParameters>     

In this example, we're constructing a simple search parameters type entity, which fetches its state from various elements on the page. An instance of SearchParametersEntity is created (using the default constructor) and then each of the property parameters are evaluated and applied to the properties of the object.

How Does It Work?

The way the code works is as follows:

  • ASP.NET evaluates the arguments group for the data source by calling Evaluate on the ParameterCollection. This returns a dictionary of name to value mappings for each evaluated parameter.
  • When the ParameterCollection is evaluating the ObjectParameter, we look at the value of the TypeName attribute and instantiate the appropriate type dynamically.
  • The ObjectParameter has its own ParameterCollection (the 'Properties' property) that is evaluated.
  • We map each of the returned values from the Properties ParameterCollection onto the properties of the activated type through reflection.

Points to Note

  • Always implement a ToString() on objects you create for parameters, as ASP.NET uses the ToString() value for the caching key when you enable caching on data sources.
  • You can nest these arbitrarily to build up insanely large and complex object trees if you so desire.
  • You can use any number of these to allow calling of code that requires multiple complex parameter inputs as arguments.
  • Please ensure that you add the 'tagprefix' element to your web.config to register the parameter if you try referencing the library from your own code.

Revision History

  • 3rd Februrary, 2009 - Initial submission to CodeProject

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Steven James Gray
Software Developer (Senior) Insurance Industry
United Kingdom United Kingdom
Member
Steve Gray is a Senior Developer at a British insurance company, working on a popular aggregator. When he's not writing ASP .NET, it's because there's SQL or WCF to write instead.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat About Update/InsertmemberMark Pierson19 Jun '09 - 8:47 
Does this work for update/insert parameters as well?
AnswerRe: What About Update/InsertmemberSteven James Gray11 Oct '09 - 18:13 
This will work pretty much the same for Insert, Update, Delete and Select parameters. If you have your own control that leverages the ParameterCollection type for some configurability, you'll also be able to use it tere.
GeneralPostback behaviourmemberbuehlert12 Feb '09 - 2:06 
Thanks for this great component, it works like a charm.
I have one question concerning the behaviour of complex parameters within object datasources during postbacks.
I set e.g. some parameters (also the complex) in the Page_load event when the page is loaded the first time. Once there is a postback, I expect that all parameters are still available (they are for elementary data types). But the complex data types are NULL then.
Is there a hint or did I implement anything wrong?
Thanks in advance.
 
Annotation:
I used the "ActivatedInstance" property of the object parameter in the Page_Load event to set the desired object instance.
GeneralRe: Postback behaviourmemberbuehlert12 Feb '09 - 3:25 
What I do currently as a workaround is to store the complex data type in the view state (of course it has to be serializable) and set it again in the ObjectDataSource_Selecting event.
This works for me but maybe there is a better solution.
GeneralRe: Postback behaviourmemberSteven James Gray12 Feb '09 - 8:53 
Are your types serializable? (Also implement a decent ToString for caching, as per the article). Also bear in mind the following...
 
Don't forget as well that the data-sources are not needed on post-back (unless performing insert/update/delete, or re-select after any of the previous). Any call to DataBind() will automatically rebuild the parameter.
 
Once you've loaded the data into say, a repeater, the object is stored as the viewstate of that control (and not in the ObjectDataSource). During a post-back the repeater or other control will not re-call the data source, but instead reconstruct itself from the viewstate.
GeneralDataBindingmember_phi_11 Feb '09 - 4:20 
Hi Steven,
 
your Complex Parameter Support is a great feature.
Do you have any experience with DataBinding, especially 2-way DataBinding?
 
In my case i've got a complex object and I would like to update its references.
Like Person & Address and I would like to update the Person's address by choosing one of several addresses out of a drop-down-list.
 
Best
- phi
GeneralRe: DataBindingmemberSteven James Gray12 Feb '09 - 8:55 
You could achieve this by:
 
1) Implement address as a serializable object with a ToString() that displays the fully formatted address.
 
2) Bind a list of 'Address' onto a DropDownList with an ObjectDataSource. The trick here is that the ToString() is the default value for the drop-downs text display.
 
3) Build a complex parameter value for your insert using the article example, and for the Address specifiy
 
<properties>
   <asp:controlparameter name="Address" type="Object" controlid="YourDropDownLIst" runat="Server" xmlns:asp="#unknown" />
</properties>
 
That *might* work. Note the posting thing on this site has added the xmlns bit on there. I can't get rid of it....

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 3 Feb 2009
Article Copyright 2009 by Steven James Gray
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid