I’ve spent the last couple of hours trying to work something out that boggled my mind.
I have a base4 class that I wrapped in a Dataobject in my Businesslayer.
On my page (actually in a user control) i have a gridview that binds to an object datasource and stores the list of retrieved values in the viewstate. The business object is paged server side and supports sorting.
The business object looks at it’s simplest like this :
There are 2 methods for every retrieval function. the first method is the method that fetches the list of data to display and the second method just gives the full row count. There are 2 methods because their signatures need to be the same.
What i then did was handle the objectSelected event of the object datasource and pass the e.ReturnValue to a property of my control that stores the list in viewstate.
When i select something in the gridview I always got an exception thrown telling me that the variable in viewstate was null.
After a lot of debugging sessions (in a solution that takes about 10 minutes or a little longer to build) I found out that i get a value in the viewstate but then lost it again in the same operation.
And that’s when it hit me. The object datasource selected event gets also fired for the count method and empties the viewstate. So now I have a second round trip to my database to stick the values in the viewstate and everything works.
So if anybody comes across a similar problem this is how i got around it.
I do realize the importance of caching
The objectdatasource definition:
EnablePaging=“True” MaximumRowsParameterName=“pageSize” OldValuesParameterFormatString=“original_{0}”
SelectCountMethod=“GetByCompanyNameCount” SelectMethod=“GetByCompanyName” SortParameterName=“sortExpression”
TypeName=“Smap.Businesslogic.Contacts.ContactSource” EnableViewState=“true” OnSelected=“ObjectDataSource1_Selected”>
Type=“String” />
And the objectdatasource selected event :
protectedvoid ObjectDataSource1_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
if (e.OutputParameters.Keys.Count > 0)
{
foreach (object key in e.OutputParameters.Keys)
{
Response.Write(string.Format(“Key: {0}, Value: {1}, Type: {2}
“,key,e.OutputParameters[key],e.OutputParameters[key].GetType()));
}
}
Contacts = source.GetByCompanyNameByPage(SearchList.Text, gvContacts.SortExpression, gvContacts.PageIndex, gvContacts.PageSize) asItemList<Contact>;
}
The business object :
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Smap.Data;
using Base4.Storage;
namespace Smap.Businesslogic.Contacts
{
[DataObject]
publicclassContactSource
{
[DataObjectMethod(DataObjectMethodType.Select,true)]
publicIItemList
{
//Set the default sortexpression is none is provided.
if (string.IsNullOrEmpty(sortExpression))
sortExpression = “CompanyName”;
//The objectdatasource returns the index of the first row that is to be retrieved
//Base4 needs the page number
int pageNumber = getPageNumber(startRowIndex, pageSize);
//initialise the object path with the sort expression
ObjectPath path = initialiseObjectPath(sortExpression);
//Add our parameter
path.New(“CompanyName”).LIKE(string.Format(“%{0}%”, searchString));
//Tell base4 which pages that need to be retrieved.
path.PageNumber = pageNumber;
path.PageSize = pageSize;
//Return our list to the object datasource
returnStorageContext.Find
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
publicIItemList
{
//Set the default sortexpression is none is provided.
if (string.IsNullOrEmpty(sortExpression))
sortExpression = “CompanyName”;
//initialise the object path with the sort expression
ObjectPath path = initialiseObjectPath(sortExpression);
//Add our parameter
path.New(“CompanyName”).LIKE(string.Format(“%{0}%”, searchString));
//Tell base4 which pages that need to be retrieved and their length.
//The gridview returns the page index which is zero-based, base4 asks for a page number which starts at 1.
path.PageNumber = ++pageNumber;
path.PageSize = pageSize;
returnStorageContext.Find
}
publicint GetByCompanyNameCount(string searchString, string sortExpression, int startRowIndex, int pageSize)
{
//Gets the count of all the contacts.
returnStorageContext.FindAll
}
privateObjectPath initialiseObjectPath(string sortExpression)
{
ObjectPath path = newObjectPath();
if (sortExpression.Trim().Length > 0)
{
string[] sortParams = sortExpression.Split(“,”.ToCharArray());
foreach (string s in sortParams)
{
OrderByDirection direction = s.IndexOf(“DESC”) > -1 ? OrderByDirection.Descending : OrderByDirection.Ascending;
string orderby = s.Substring(0, s.IndexOf(“DESC”) > -1 ? s.IndexOf(“DESC”) : s.Length);
path.AddOrderBy(orderby, direction);
}
}
return path;
}
privateint getPageNumber(int startRowIndex, int pageSize)
{
//if the start index is smaller than 0 return 0 otherwise return the index of the current page.
int number = startRowIndex <= 0 ? 0 : (int)Math.Ceiling(Convert.ToDouble(startRowIndex / pageSize));
//make our zero-based index into a number starting at 1;
return ++number;
}
}
}

