Introduction
The System.Web.UI.WebControls.ObjectDataSource
class enables a developer to automatically bind the public properties of a business object to a control, such as a DetailsView
control.
This is supposed to be easy, but after a week of research including support from Microsoft via their Managed Newsgroups, there is no equivalent example to date. For example, MS insisted that the developer must at least write an event handler that processes each bound property, but the attached example proves this to be unnecessary.
Installation
The example is a file system based web site. Unzip it and add it as an existing web site to a solution. Set the start page. Start the debugger.
The Business Object
Object data binding does require the business object to have a select and update method, but this example does not require each property to be passed as a separate parameter to that update method. The update method in this example takes as its sole parameter an object whose properties have been automatically updated with the values currently in the DetailsView
control. The update method places the object in the Session because elsewhere in the application domain (outside the update method) the updated values would either have been accessible only in the form of a collection in the DetailsView
or else would not have been accessible at all (not even in the DetailsView
).
public class DO
{
private string _ID;
private bool _IsTest;
public string ID { get { return _ID; } set { _ID = value; } }
public bool IsTest { get { return _IsTest; } set { _IsTest = value; } }
public DO()
{
ID = "Test";
IsTest = false;
}
public static DO Select()
{
DO obj = (DO)HttpContext.Current.Session["DO"];
if (obj == null) obj = new DO();
return obj;
}
public void Update(DO obj)
{
HttpContext.Current.Session["DO"] = obj;
}
}
The CodeBehind
If the developer were writing an event handler for a button and needed to get a business object whose properties contain the values currently on screen, the call to DetailsView.UpdateItem
will force a call to the update method, and pass it an updated object. The developer can then retrieve the updated object using the Select
method.
public partial class DOTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnRunTest_Click(object sender, EventArgs e)
{
DetailsView1.UpdateItem(true);
DO obj = DO.Select();
}
}
The ASPX Page
The page contains a Button
, an ObjectDataSource
, and a DetailsView
control. The contents of the ASPX file below were generated automatically by the designer.
<body>
<form id="form1" runat="server">
<div> </div>
<asp:Button ID="btnGetRate" runat="server"
Height="44px" OnClick="btnRunTest_Click"
Style="z-index: 100; left: 208px; position: absolute; top: 72px"
Text="Run Test" Width="73px" />
<asp:DetailsView ID="DetailsView1"
runat="server" DataSourceID="ObjectDataSource1"
DefaultMode="Edit" Height="50px"
Style="z-index: 101; left: 192px; position: absolute;
top: 160px" Width="125px" AutoGenerateRows="False">
<Fields>
<asp:BoundField DataField="ID"
HeaderText="ID" SortExpression="ID" />
<asp:CheckBoxField DataField="IsTest"
HeaderText="IsTest" SortExpression="IsTest" />
</Fields>
</asp:DetailsView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="Select" TypeName="DO"
UpdateMethod="Update" DataObjectTypeName="DO">
</asp:ObjectDataSource>
</form>
</body>
You could also manually define template fields like the following:
(Note that some examples, including sample code from MS use Eval
instead of Bind
, and thus a business object sent to the update method would not contain updated values.)
<Fields>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:TextBox ID="tbID" runat="server" Text='<%# Bind("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="IsTest">
<ItemTemplate>
<asp:CheckBox ID="cbIsTest"
runat="server" Checked='<%# Bind("IsTest") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Fields>