GridView Insert with ObjectDataSource: Lessons Learnt

Was playing around today with implementing a full CRUD interface to a Database table using GridView and ObjectDataSource. I had a bit of trouble getting Insert functionality to work and here’s what I learnt:

DataObjectTypeName SHOULD BE OMITTED if you are using Insert operations via your ODS.

Setting the ODS property DataObjectTypeName is meant to allow you to pass a Business or Domain object as a single parameter, rather than a list of parameters, one per member, to your ODS Inserts and Updates. While this seems to work fine for Updates, the ODS Insert will fail since its internal Dictionary of Object members is not initialised. This appears to be a bug in the ODS.

There are a couple of workarounds for this: you can create the Dictionary yourself from the ODS DataSource, or you can create a your custom Business object from the InsertParameter list. But if you don’t feel in the mood for workarounds you are stuck with omitting the DataObjectTypeName property and specifying the list of parameters to your Insert in the markup for the ODS

InsertParameters
asp:Parameter Name="CountryCode" /
asp:Parameter Name="CountryName" /
asp:Parameter Name="ISDCode" /
/InsertParameters

ODS Delete Parameter Will Be Inferred From DataKeys Member Of The GridView

Given a GridView of the following definition:
asp:GridView ID="gvTrial" runat="server" DataKeyNames="CountryCode"

NO DeleteParameter is required in the ODS markup and the DeleteMethod with the single parameter string CountryCode will be invoked from the TypeName (DataAccess) class specified in the ODS markup.

LinkButtons Defined in the GridView Control Template Will Trigger The ODS TypeName (DataAccess) Methods
You just need to give them the standard CommandNames that GridViews give to their Command Buttons. So given the following Button Definitions in the GridView Template:

asp:TemplateField
EditItemTemplate
asp:LinkButton ID="btnUpdate" runat="server" Text="Update" CommandName="Update" /
asp:LinkButton ID="btnCancel" runat="server" Text="Cancel" CommandName="Cancel" /
/EditItemTemplate
ItemTemplate
asp:LinkButton ID="btnEdit" runat="server" Text="Edit" CommandName="Edit" /
/ItemTemplate
FooterTemplate
asp:LinkButton ID="btnInsert" runat="server" Text="Insert" OnClick="lbInsert_OnClick" /
/FooterTemplate
/asp:TemplateField
asp:CommandField ShowDeleteButton="true" /

The Update and Delete methods on the TypeName (DataAccess) class will be fired automatically when the Update and Delete buttons are clicked.

Firing Insert From GridView Footer

This link shows the basic interface I used, with the Insert operation being fired from a LinkButton in the GridView Footer Row. As noted above, the Insert Parameters must be specified in the ODS Markup.

Insert From GridView Footer Where DataSource Is Empty
If your datasource is empty, the GridView will not render, so you wont get a Footer and you wont be able to Insert. So, add an empty record to the DataSource On the ODS SelectMethod, then hide the empty row during OnRowDataBound

The Final ODS

asp:ObjectDataSource runat="server" ID="odsCountry" TypeName="CountrySource" OnInserting="odsCountry_Inserting"
SelectMethod="GetCountries" UpdateMethod="UpdateCountry" InsertMethod="InsertCountry" DeleteMethod="DeleteCountry">
InsertParameters>
asp:Parameter Name="CountryCode" /
asp:Parameter Name="CountryName" /
asp:Parameter Name="ISDCode" /
/InsertParameters
/asp:ObjectDataSource

The GridView


asp:GridView ID="gvTrial" runat="server" DataKeyNames="CountryCode" EmptyDataText="No country data" DataSourceID="odsCountry"
AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false" ShowFooter="true" OnRowDataBound="gvTrial_RowDataBound"

/EditItemTemplate
ItemTemplate
asp:LinkButton ID="btnEdit" runat="server" Text="Edit" CommandName="Edit" /
/ItemTemplate
FooterTemplate
asp:LinkButton ID="btnInsert" runat="server" Text="Insert" OnClick="lbInsert_OnClick" /
/FooterTemplate
/asp:TemplateField
asp:TemplateField
EditItemTemplate
asp:TextBox ID="tbCountryCode" runat="server" Text=''/asp:TextBox
/EditItemTemplate
ItemTemplate
asp:Label ID="lbCountryCode" runat="server" Text=''/asp:Label
/ItemTemplate
FooterTemplate
asp:TextBox ID="tbNewCountryCode" runat="server"></asp:TextBox
/FooterTemplate
/asp:TemplateField
asp:TemplateField
EditItemTemplate
asp:TextBox ID="tbCountryName" runat="server" Text=''/asp:TextBox
/EditItemTemplate
ItemTemplate
asp:Label ID="lbCountryName" runat="server" Text=''/asp:Label
/ItemTemplate
FooterTemplate
asp:TextBox ID="tbNewCountryName" runat="server"/asp:TextBox
/FooterTemplate
/asp:TemplateField
asp:TemplateField
EditItemTemplate
asp:TextBox ID="tbISDCode" runat="server" Text=''/asp:TextBox
/EditItemTemplate
ItemTemplate
asp:Label ID="lbISDCode" runat="server" Text=''>/asp:Label
/ItemTemplate
FooterTemplate
asp:TextBox ID="tbNewISDCode" runat="server"></asp:TextBox
/FooterTemplate
/asp:TemplateField
asp:CommandField ShowDeleteButton="true" /

/Columns
/asp:GridView

The TypeName (DataAccess) Class

Since DataObjectTypeName is omitted you MUST specify all parameters to the Insert and Update Methods. You cannot use your Business Class, which in my case would be ‘Country’. Use the MSDN example as your basic template:

public void UpdateCountry(string CountryCode, string CountryName, string ISDCode)
{
…whatever…
}

public void InsertCountry(string CountryCode, string CountryName, string ISDCode)
{
…whatever…
}

public void DeleteCountry(string CountryCode)
{
…whatever…
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: