WEBSITE

ASP.NET 4.0 : Data Source Components (part 3) - The ObjectDataSource Control - Implementing Data Retrieval

12/30/2013 1:53:09 AM

3. The AccessDataSource Class

The AccessDataSource control is a data source control that represents a connection to an Access database. It is based on the SqlDataSource control and provides a simpler, made-to-measure programming interface. As a derived class, AccessDataSource inherits all members defined on its parent and overrides a few of them. In particular, the control replaces the ConnectionString and ProviderName properties with a more direct DataFile property. You set this property to the .mdb database file of choice. The data source control resolves the file path at run time and uses the Microsoft Jet 4 OLE DB provider to connect to the database.

Note

AccessDataSource actually inherits from SqlDataSource, and for this reason it can’t make base members disappear, as hinted at earlier. AccessDataSource doesn’t really replace the ConnectionString and ProviderName properties; it overrides them so that an exception is thrown whenever someone attempts to set their value. Another property overridden only to throw exceptions is SqlCacheDependency. This feature, of course, is not supported by the Access database.


Working with an Access Database

The following code shows how to use the AccessDataSource control to open an .mdb file and bind its content to a drop-down list control. Note that the control opens Access database files in read-only mode by default.

<asp:AccessDataSource runat="server" ID="MyAccessSource"
DataFile="~/App_Data/nwind.mdb"
SelectCommand="SELECT * FROM Customers" />
Select a Customer:
<asp:DropDownList runat="server" DataSourceId="MyAccessSource" />

Several features of the AccessDataSource control are inherited from the base class, SqlDataSource. In fact, the Access data source control is basically a SQL data source control optimized to work with Access databases. Like its parent control, the AccessDataSource control supports two distinct data source modes—DataSet and DataReader, depending on the ADO.NET classes used to retrieve data. Filtering can be applied to the selected data only if the fetch operation returns a DataSet. Caching works as on the parent class except for the SqlCacheDependency feature.

Updating an Access Database

The AccessDataSource can also be used to perform insert, update, or delete operations against the associated database. This is done using ADO.NET commands and parameter collections. Updates are problematic for Access databases when performed from within an ASP.NET application because an Access database is a plain file and the default account of the ASP.NET process (ASPNET or NetworkService, depending on the host operating system) might not have sufficient permission to write to the database file. For the data source updates to work, you should grant write permission to the ASP.NET account on the database file. Alternatively, you can use a different account with adequate permission.

Note

Most Internet Service Providers normally give you one directory in which ASPNET and NetworkService accounts have been granted the write permission. In this case, you just place your Access file in this directory and you can read and write seamlessly. In general, though, Access databases are plain files and, as such, are subject to the security rules of ASP.NET.


4. The ObjectDataSource Control

The ObjectDataSource class enables user-defined classes to associate the output of their methods to data-bound controls. Like other data source controls, ObjectDataSource supports declarative parameters to allow developers to pass page-level variables to the object’s methods. The ObjectDataSource class makes some assumptions about the objects it wraps. As a consequence, an arbitrary class can’t be used with this data source control. In particular, bindable classes are expected to have a default constructor, be stateless, and have methods that easily map to select, update, insert, and delete semantics. Also, the object must perform updates one item at a time; objects that update their state using batch operations are not supported. The bottom line is that managed objects that work well with ObjectDataSource are designed with this data source class in mind.

4.1 Programming Interface of ObjectDataSource

The ObjectDataSource component provides nearly the same programmatic interface (events, methods, properties, and associated behaviors) as the SqlDataSource, with the addition of three new events and a few properties. The events the ObjectDataSource fires are related to the lifetime of the underlying business object the ObjectDataSource is bound to—ObjectCreating, ObjectCreated, and ObjectDisposing. Table 9 lists other key properties of ObjectDataSource.

Table 9. Main Properties of ObjectDataSource
PropertyDescription
ConvertNullToDBNullIndicates whether null parameters passed to insert, delete, or update operations are converted to System.DBNull. This property is set to false by default.
DataObjectTypeNameGets or sets the name of a class that is to be used as a parameter for a Select, Insert, Update, or Delete operation.
DeleteMethod, DeleteParametersGets or sets the name of the method and related parameters used to perform a delete operation.
EnablePagingIndicates whether the control supports paging.
FilterExpression, FilterParametersIndicates the filter expression (and parameters) to filter the output of a select operation.
InsertMethod, InsertParametersGets or sets the name of the method and related parameters used to perform an insert operation.
MaximumRowsParameterNameIf the EnablePaging property is set to true, indicates the parameter name of the Select method that accepts the value for the number of records to retrieve.
OldValuesParameterFormatStringGets or sets a format string to apply to the names of any parameters passed to the Delete or Update methods.
SelectCountMethodGets or sets the name of the method used to perform a select count operation.
SelectMethod, SelectParametersGets or sets the name of the method and related parameters used to perform a select operation.
SortParameterNameGets or sets the name of an input parameter used to sort retrieved data. It raises an exception if the parameter is missing.
StartRowIndexParameterNameIf the EnablePaging property is set to true, indicates the parameter name of the Select method that accepts the value for the starting record to retrieve.
UpdateMethod, UpdateParametersGets or sets the name of the method and related parameters used to perform an update operation.

The ObjectDataSource control uses reflection to locate and invoke the method to handle the specified operation. The TypeName property returns the fully qualified name of the assembly that defines the class to call. If the class is defined in the App_Code directory, you don’t need to indicate the assembly name. Otherwise, you use a comma-separated string in the form of [classname, assembly]. Let’s see an example.

Warning

Having too many classes in the App_Code directory can become a nightmare at development time because any changes to any files will cause Visual Studio .NET to recompile the whole set of files in the project. If you prefer, it’s completely reasonable to encapsulate your business object in a separate assembly and have your Web application simply reference that assembly.


4.2 Implementing Data Retrieval

The following code snippet illustrates a class that can be used with an object data source. The class represents employees and takes advantage of two other helper classes (at the very minimum): Employee and EmployeeCollection. The class Employee contains information about the entity being represented; the class EmployeeCollection represents a collection of employees. The behavior of the entity “employee” is codified in a bunch of methods exposed out of the gateway class—Employees.

public class Employees
{
public static string ConnectionString {
...
}
public static void Load(int employeeID) {
...
}
public static EmployeeCollection LoadAll() {
...
}
public static EmployeeCollection LoadByCountry(string country) {
...
}
public static void Save(Employee emp) {
...
}
public static void Insert(Employee emp) {
...
}
public static void Delete(int employeeID) {
...
}
...
}



If you don’t use static methods, the worker class you use with ObjectDataSource must have a default parameterless constructor. Furthermore, the class should not maintain any state.

Warning

Using static methods in classes that represent the gateway to a database table is fine from an architectural viewpoint, but it might pose practical problems with unit testing. What if you test a business class that calls the data access layer (DAL) internally and the DAL fails? Can you figure out what really happened? Does the business class work or not?

To effectively test a business layer that calls into a DAL, you need to focus on the object under test. Mock objects come to the rescue. Mock objects are programmable polymorphic objects that present themselves as others. So you can use mock objects to wrap the DAL and make it always return valid results. In this way, any anomalies are the result of non-DAL classes. The point is that toolkits that provide mock objects typically don’t like static methods. That’s why instance methods might be preferable in gateway classes of a DAL.


The worker class must be accessible from within the .aspx page and can be bound to the ObjectDataSource control, as shown here:

<asp:ObjectDataSource runat="server" ID="MyObjectSource"
TypeName="Core35.DAL.Employees"
SelectMethod="LoadAll" />

When the HTTP runtime encounters a similar block in a Web page, it generates code that calls the LoadAll method on the specified class. The returned data—an instance of the EmployeeCollection—is bound to any control that links to MyObjectSource via the DataSourceID property. Let’s take a brief look at the implementation of the LoadAll method:

public static EmployeeCollection LoadAll()
{
EmployeeCollection coll = new EmployeeCollection();

using (SqlConnection conn = new SqlConnection(ConnectionString)
{
SqlCommand cmd = new SqlCommand("SELECT * FROM employees", conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
HelperMethods.FillEmployeeList(coll, reader);
reader.Close();
conn.Close();
}
return coll;
}

Although it’s a bit oversimplified so that it can fit in this section, the preceding code remains quite clear: you execute a command, fill in a custom collection class, and return it to the data-bound control. The only piece of code you need to write is the worker class—you don’t need to put any code in the code-behind class of the page.

<asp:DataGrid ID="grid" runat="server"
DataSourceID="MyObjectSource" />

The DataGrid receives a collection of Employee objects defined as follows:

public class EmployeeCollection : Collection<Employee>
{
}

Binding is totally seamless, even without ADO.NET container objects. (See the companion code for full details.)

The method associated with the SelectMethod property must return any of the following: an IEnumerable object such as a collection, a DataSet, a DataTable, or an Object. Preferably, the Select method is not overloaded, although ObjectDataSource doesn’t prevent you from using an overloaded method in your business classes.

Other  
  •  ASP.NET 4.0 : Data-Binding Expressions (part 2) - Other Data-Binding Methods
  •  ASP.NET 4.0 : Data-Binding Expressions (part 1) - Simple Data Binding
  •  Sharepoint 2010 : Putting Your Site on the Web - Customizing the User Experience (part 2) - Working with Page Layouts
  •  Sharepoint 2010 : Putting Your Site on the Web - Customizing the User Experience (part 1) - Working with Master Pages
  •  SharePoint 2013 and Windows Azure (part 3) - Creating a Simple Autohosted SharePoint App - Building A Client App Web Part
  •  SharePoint 2013 and Windows Azure (part 2) - Creating a Simple Autohosted SharePoint App - Building Your First Autohosted App
  •  SharePoint 2013 and Windows Azure (part 1) - Understanding SharePoint Cloud-Hosted Apps and Windows Azure
  •  Sharepoint 2013 : SharePoint Installation and Configuration - Create a New Subsite
  •  Sharepoint 2013 : Join a Server to the SharePoint Farm, Create a New Web Application, Create a New Site Collection
  •  Sharepoint 2013 : Install Without a Product Key in the Configuration File, Configure a New SharePoint Farm
  •  
    Most View
    DirectX 10 Game Programming : 3D Introduction - Optimizing the Drawing Using Index Buffers
    Thin Berry Client (Part 1)
    ASP.NET 4.0 : Data Source Components (part 5) - The ObjectDataSource Control - Setting Up for Paging , Updating and Deleting Data
    Windows Server 2008 R2 networking : Overview of Windows Server 2008 R2 Networking
    EVGA Z87 Stinger 2013
    The Gaming Mouse: Ozone Neon
    Introducing Windows Presentation Foundation and XAML : Building WPF Applications Using Visual Studio 2010 (part 1)
    SQL Server 2012 : Isolation Levels (part 2) - Repeatable Read Isolation Level,Snapshot Isolation Level, Isolation Levels in ADO.NET
    Microsoft Lync Server 2010 : Microsoft Communicator Client for Macintosh - Getting Around in the Client
    Fujifilm X-E1 - A Retro Camera That Inspires (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
    Top 10
    Review : Acer Aspire R13
    Review : Microsoft Lumia 535
    Review : Olympus OM-D E-M5 Mark II
    TomTom Runner + MultiSport Cardio
    Timex Ironman Run Trainer 2.0
    Suunto Ambit3 Peak Sapphire HR
    Polar M400
    Garmin Forerunner 920XT
    Sharepoint 2013 : Content Model and Managed Metadata - Publishing, Un-publishing, and Republishing
    Sharepoint 2013 : Content Model and Managed Metadata - Content Type Hubs