Extending the ObjectDataSource Control In this final section, we examine two methods of extending the ObjectDataSource control. You learn how to create a custom data source control by deriving a new control from the ObjectDataSource control. You also learn how to create custom parameters that can be used with the ObjectDataSource (and other DataSource controls). Creating a Custom ObjectDataSource Control If you discover that you are declaring an ObjectDataSource control with the same properties on multiple pages, then it makes sense to derive a new control from the ObjectDataSource control that has these properties by default. That way, you can simply declare the derived control in a page. For example, if you are displaying a list of movies in multiple pages in your website, then it would make sense to create a specialized MovieDataSource control. The control in Listing 15.37, named the MovieDataSource control, derives from the base ObjectDataSource control class. The MovieDataSource control represents the MoviesComponent, which is also contained in Listing 15.37. Listing 15.37. MovieDataSource.vb Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Web.Configuration Imports System.Web.UI.WebControls Namespace AspNetUnleashed.Samples Public Class MovieDataSource Inherits ObjectDataSource Public Sub New() Me.TypeName = "AspNetUnleashed.Samples.MoviesComponent" Me.SelectMethod = "GetMovies" End Sub End Class Public Class MoviesComponent Private ReadOnly _conString As String Public Function GetMovies() As SqlDataReader ' Initialize connection Dim con As New SqlConnection(_conString) ' Initialize command Dim cmd As New SqlCommand() cmd.Connection = con cmd.CommandText = "SELECT Title,Director,DateReleased FROM Movies" ' Execute command con.Open() Return cmd.ExecuteReader(CommandBehavior.CloseConnection) End Function Sub New() _conString = WebConfigurationManager.ConnectionStrings("Movies").ConnectionString End Sub End Class End Namespace | The MovieDataSource control initializes the base ObjectDataSource control's TypeName and SelectMethod properties in its constructor. The TypeName is assigned the fully qualified name of the MoviesComponent. The page in Listing 15.38 illustrates how you can use the MovieDataSource control in a page (see Figure 15.11). Figure 15.11. Using the MovieDataSource control to display movies. Listing 15.38. ShowMovieDataSource.aspx <%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="AspNetUnleashed.Samples" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Show Movie DataSource</title> </head> <body> <form runat="server"> <div> <asp:GridView DataSource Runat="server" /> <custom:MovieDataSource Runat="server" /> </div> </form> </body> </html> | Notice that the custom control must be registered with a <%@ Register %> directive at the top of Listing 15.38. After you register the control, you can simply declare the MovieDataSource control in the page to represent the contents of the Movies database table. Note As an alternative to registering the MovieDataSource control in a page, you can register the control for an entire application in the web configuration file within the <pages> element. Creating Custom Parameter Objects The standard DataSource Parameter objects included in the ASP.NET Framework enable you to represent objects such as query string values, items from Session state, and the values of control properties. If none of the standard Parameter objects satisfy your requirements, you always have the option of creating a custom Parameter object. You create a custom Parameter object by deriving a new class from the base Parameter class. In this section, we create two custom parameters. The first is a UsernameParameter that automatically represents the current username. Next is a PagePropertyParameter that represents the current value of a property contained in the page. Creating a Username Parameter The UsernameParameter class is contained in Listing 15.39. Notice that the class in Listing 15.39 derives from the Parameter class and overrides the Evaluate() method of the base class. The Evaluate() method determines what the parameter represents. Listing 15.39. UsernameParameter.vb [View full width] Imports System Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Namespace MyControls Public Class UsernameParameter Inherits Parameter Protected Overrides Function Evaluate(ByVal context As HttpContext, ByVal control As Control) As Object If Not context Is Nothing Then Return context.User.Identity.Name Else Return Nothing End If End Function End Class End Namespace | The UsernameParameter returns the current username. The parameter retrieves this information from the current HttpContext passed to the Evaluate() method. The UsernameParameter is used in the page in Listing 15.40. Listing 15.40. ShowUsernameParameter.aspx <%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="MyControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <style type="text/css"> .guestbook td,.guestbook th { padding:5px; font:14px Arial,Sans-Serif; } </style> <title>Show Username Parameter</title> </head> <body> <form runat="server"> <div> <asp:FormView DataSource DefaultMode="Insert" Runat="server"> <InsertItemTemplate> <asp:Label Text="Comment:" AssociatedControl Runat="server" /> <br /> <asp:TextBox Text='<%# Bind("comment") %>' TextMode="MultiLine" Columns="50" Rows="4" Runat="server" /> <br /> <asp:Button Text="Add Entry" CommandName="Insert" Runat="server" /> </InsertItemTemplate> </asp:FormView> <hr /> <asp:GridView DataSource Css Runat="server" /> <asp:ObjectDataSource TypeName="GuestbookComponent" SelectMethod="GetEntries" InsertMethod="AddEntry" Runat="server"> <InsertParameters> <custom:UsernameParameter name="username" /> </InsertParameters> </asp:ObjectDataSource> </div> </form> </body> </html> | The UsernameParameter is declared in the ObjectDataSource control's InsertParameters collection. When you add a new entry to the guestbook, your username is added automatically (see Figure 15.12). Figure 15.12. Inserting records with the UsernameParameter. Creating a Page Property Parameter The PagePropertyParameter enables you to represent an arbitrary property of the current page. The property being represented can return whatever type of value you want. The code for the PagePropertyParameter is contained in Listing 15.41. Listing 15.41. PagePropertyParameter.vb [View full width] Imports System Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Namespace MyControls Public Class PagePropertyParameter Inherits Parameter Private _propertyName As String Protected Overrides Function Evaluate(ByVal context As HttpContext, ByVal control As Control) As Object Return DataBinder.Eval(control.Page, PropertyName) End Function Public Property PropertyName() As String Get Return _propertyName End Get Set(ByVal Value As String) _propertyName = value End Set End Property End Class End Namespace | The component in Listing 15.41 overrides the Evaluate method of the base Parameter class. The DataBinder.Eval() method is used to return the value of a property of the current page. The page in Listing 15.42 uses the PagePropertyParameter to represent a property of the page named CurrentUsername. This property returns the current username. Listing 15.42. ShowPagePropertyParameter.aspx <%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="MyControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> Public ReadOnly Property CurrentUsername() As String Get Return User.Identity.Name End Get End Property </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <style type="text/css"> .guestbook td,.guestbook th { padding:5px; font:14px Arial,Sans-Serif; } </style> <title>Show Page Property Parameter</title> </head> <body> <form runat="server"> <div> <asp:FormView DataSource DefaultMode="Insert" Runat="server"> <InsertItemTemplate> <asp:Label Text="Comment:" AssociatedControl Runat="server" /> <br /> <asp:TextBox Text='<%# Bind("comment") %>' TextMode="MultiLine" Columns="50" Rows="4" Runat="server" /> <br /> <asp:Button Text="Add Entry" CommandName="Insert" Runat="server" /> </InsertItemTemplate> </asp:FormView> <hr /> <asp:GridView DataSource Css Runat="server" /> <asp:ObjectDataSource TypeName="GuestbookComponent" SelectMethod="GetEntries" InsertMethod="AddEntry" Runat="server"> <InsertParameters> <custom:PagePropertyParameter Name="Username" PropertyName="CurrentUsername" /> </InsertParameters> </asp:ObjectDataSource> </div> </form> </body> </html> | In Listing 15.42, the PagePropertyParameter is used to represent the current username. Because the PagePropertyParameter can represent any page property, the parameter could represent any type of value. |