Tutorial 17: Examining the Events Associated with Inserting, Updating, and Deleting

 

Scott Mitchell

March 2007

Summary: Extend the built-in inserting, updating, and deleting capabilities of ASP.NET data Web controls, and customize the editing interface to update only a subset of the product fields, with this tutorial from Scott Mitchell. (29 printed pages)

Download the code for this sample.

Contents of Tutorial 17 (Visual Basic)

Introduction
Step 1: Updating a Product's ProductName and UnitPrice Fields
Improving the UnitPrice Formatting
Step 2: Prohibiting NULL UnitPrices
Step 3: Providing an Interface to Add New Products
Step 4: Assigning Values to the CategoryID and SupplierID Parameters
Conclusion

Introduction

When using the built-in inserting, editing, or deleting features of the GridView, DetailsView, or FormView controls, a variety of steps transpire when the end user completes the process of adding a new record or updating or deleting an existing record. As we discussed in the previous tutorial, when a row is edited in the GridView the Edit button is replaced by Update and Cancel buttons and the BoundFields turn into TextBoxes. After the end user updates the data and clicks Update, the following steps are performed on postback:

  1. The GridView populates the UpdateParameters of its ObjectDataSource with the edited record's unique identifying field(s) (by way of the DataKeyNames property), along with the values entered by the user.
  2. The GridView invokes the Update() method of its ObjectDataSource, which in turn invokes the appropriate method in the underlying object (ProductsDAL.UpdateProduct, in our previous tutorial).
  3. The underlying data, which now includes the updated changes, is rebound to the GridView.

During this sequence of steps, a number of events fire, enabling us to create event handlers to add custom logic, where needed. For example, prior to step 1, the RowUpdating event of the GridView fires. We can, at this point, cancel the update request if there is some validation error. When the Update() method is invoked, the Updating event of the ObjectDataSource fires, providing an opportunity to add or customize the values of any of the UpdateParameters. After the method of the underlying object of the ObjectDataSource has completed executing, the Updated event of the ObjectDataSource is raised. An event handler for the Updated event can inspect the details about the update operation, such as how many rows were affected and whether or not an exception occurred. Finally, after step 2, the RowUpdated event of the GridView fires; an event handler for this event can examine additional information about the update operation that was just performed.

Figure 1 depicts this series of events and steps when updating a GridView. The event pattern in Figure 1 is not unique to updating with a GridView. Inserting, updating, or deleting data from the GridView, DetailsView, or FormView precipitates the same sequence of pre-level and post-level events for both the data Web control and the ObjectDataSource.

Click here for larger image

Figure 1. A series of pre-level and post-level events fire, when updating data in a GridView. (Click on the picture for a larger image.)

In this tutorial, we'll examine using these events to extend the built-in inserting, updating, and deleting capabilities of the ASP.NET data Web controls. We'll also see how to customize the editing interface to update only a subset of the product fields.

Step 1: Updating a Product's ProductName and UnitPrice Fields

In the editing interfaces from the previous tutorial, all product fields that were not read-only had to be included. If we were to remove a field from the GridView—say, QuantityPerUnit—when updating the data, the data Web control would not set the ObjectDataSource's QuantityPerUnit UpdateParameters value. The ObjectDataSource would then pass in a NULL value into the UpdateProduct method of the Business-Logic Layer (BLL), which would change the edited database record's QuantityPerUnit column to a NULL value. Similarly, if a required field—such as ProductName—is removed from the editing interface, the update will fail with a Column 'ProductName' does not allow nulls exception. The reason for this behavior is that the ObjectDataSource was configured to call the UpdateProduct method of the ProductsBLL class, which expected an input parameter for each of the product fields. Therefore, the UpdateParameters collection of the ObjectDataSource contained a parameter for each of the method's input parameters.

If we want to provide a data Web control that allows the end user to update only a subset of fields, then we must either programmatically set the missing UpdateParameters values in the Updating event handler of the ObjectDataSource or create and call a BLL method that expects only a subset of the fields. Let's explore the latter approach.

Specifically, let's create a page that displays just the ProductName and UnitPrice fields in an editable GridView. The editing interface of this GridView will allow the user to update only the two displayed fields, ProductName and UnitPrice. Because this editing interface only provides a subset of a product's fields, we must create either an ObjectDataSource that uses the UpdateProduct method of the existing BLL and has the missing product field values set programmatically in its Updating event handler or a new BLL method that expects only the subset of fields defined in the GridView. For this tutorial, let's use the latter option and create an overload of the UpdateProduct method—one that takes in just three input parameters: productName, unitPrice, and productID.

[System.ComponentModel.DataObjectMethodAttribute

    (System.ComponentModel.DataObjectMethodType.Update, false)]

public bool UpdateProduct(string productName, decimal? unitPrice, int 
productID)

{

    Northwind.ProductsDataTable products = 
Adapter.GetProductByProductID(productID);

    if (products.Count == 0)

        // no matching record found, return false

        return false;



    Northwind.ProductsRow product = products[0];



    product.ProductName = productName;

    if (unitPrice == null) product.SetUnitPriceNull();

      else product.UnitPrice = unitPrice.Value;



    // Update the product record

    int rowsAffected = Adapter.Update(product);



    // Return true if precisely one row was updated, otherwise false

    return rowsAffected == 1;

}

As with the original UpdateProduct method, this overload starts by checking to see if there is a product in the database that has the specified ProductID. If not, it returns false, indicating that the request to update the product information failed. Otherwise, it updates the ProductName and UnitPrice fields of the existing product record accordingly and commits the update by calling the Update() method of the TableAdapter, passing in the ProductsRow instance.

With this addition to our ProductsBLL class, we're ready to create the simplified GridView interface. Open the DataModificationEvents.aspx in the EditInsertDelete folder, and add a GridView to the page. Create a new ObjectDataSource and configure it to use the ProductsBLL class, with its Select() method mapping to GetProducts and its Update() method mapping to the UpdateProduct overload that takes in only the productName, unitPrice, and productID input parameters. Figure 2 shows the Create Data Source wizard when mapping the Update() method of the ObjectDataSource to the new UpdateProduct method overload of the ProductsBLL class.

Click here for larger image

Figure 2. Map the ObjectDataSource's Update() method to the new UpdateProduct overload. (Click on the picture for a larger image.)

Because our example will initially just need the ability to edit data, but not to insert or delete records, take a moment to indicate explicitly that the Insert() and Delete() methods of the ObjectDataSource shouldn't be mapped to any of the methods of the ProductsBLL class, by going to the INSERT and DELETE tabs and choosing (None) from the drop-down list.

Click here for larger image

Figure 3. Choose (None) from the drop-down list for the INSERT and DELETE tabs. (Click on the picture for a larger image.)

After completing this wizard, check the Enable Editing check box from the GridView's smart tag.

With the Create Data Source wizard completing and binding to the GridView, Microsoft Visual Studio has created the declarative syntax for both controls. Go to the Source view to inspect the declarative markup of the ObjectDataSource, which is shown here:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"

    OldValuesParameterFormatString="original_{0}" 
SelectMethod="GetProducts"

    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">

    <UpdateParameters>

        <asp:Parameter Name="productName" Type="String" />

        <asp:Parameter Name="unitPrice" Type="Decimal" />

        <asp:Parameter Name="productID" Type="Int32" />

    </UpdateParameters>

</asp:ObjectDataSource>

Because there are no mappings for the Insert() and Delete() methods of the ObjectDataSource, there are no InsertParameters or DeleteParameters sections. Furthermore, because the Update() method is mapped to the UpdateProduct method overload that only accepts three input parameters, the UpdateParameters section has just three Parameter instances.

Note that the OldValuesParameterFormatString property of the ObjectDataSource is set to original_{0}. This property is set automatically by Visual Studio when using the Configure Data Source wizard. However, because our BLL methods don't expect the original ProductID value to be passed in, remove this property assignment altogether from the declarative syntax of the ObjectDataSource.

Note   If you just clear out the OldValuesParameterFormatString property value from the Properties window in the Design view, the property will still exist in the declarative syntax, but it will be set to an empty string. Either remove the property altogether from the declarative syntax or, from the Properties window, set the value to the default, which is {0}.

While the ObjectDataSource only has UpdateParameters for the product's name, price, and ID, Visual Studio has added a BoundField or CheckBoxField in the GridView for each of the product's fields.

Click here for larger image

Figure 4. The GridView contains a BoundField or CheckBoxField for each of the product's fields. (Click on the picture for a larger image.)

When the end user edits a product and clicks its Update button, the GridView enumerates those fields that were not read-only. It then sets the value of the corresponding parameter in the UpdateParameters collection of the ObjectDataSource to the value entered by the user. If there is no corresponding parameter, the GridView adds one to the collection. Therefore, if our GridView contains BoundFields and CheckBoxFields for all of the product's fields, the ObjectDataSource will end up invoking the UpdateProduct overload that takes in all of these parameters, despite the fact that the declarative markup of the ObjectDataSource specifies only three input parameters (see Figure 5). Similarly, if there is some combination of non-read-only product fields in the GridView that doesn't correspond to the input parameters for an UpdateProduct overload, an exception will be raised when attempting to update.

Figure 5. The GridView will add parameters to the ObjectDataSource's UpdateParameters collection.

To ensure that the ObjectDataSource invokes the UpdateProduct overload that takes in just the product's name, price, and ID, we must restrict the GridView to having editable fields for just the ProductName and UnitPrice. This can be accomplished by removing the other BoundFields and CheckBoxFields, by setting those other fields' ReadOnly property to true, or by some combination of the two. For this tutorial, let's just remove all GridView fields except the ProductName and UnitPrice BoundFields, after which the declarative markup of the GridView will look like the following:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">

    <Columns>

        <asp:CommandField ShowEditButton="True" />

        <asp:BoundField DataField="ProductName"

          HeaderText="ProductName" SortExpression="ProductName" />

        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"

          SortExpression="UnitPrice" />

    </Columns>

</asp:GridView>

Although the UpdateProduct overload expects three input parameters, we have only two BoundFields in our GridView. This is because the productID input parameter is a primary key value and passed in through the value of the DataKeyNames property for the edited row.

Our GridView, along with the UpdateProduct overload, allows a user to edit just the name and price of a product without losing any of the other product fields.

Click here for larger image

Figure 6. The interface allows editing of just the product's name and price. (Click on the picture for a larger image.)

Note As discussed in the previous tutorial, it is vitally important that the View state of the GridView be enabled (the default behavior). If you set the EnableViewState property of the GridView to false, you run the risk of having concurrent users unintentionally delete or edit records. (See WARNING: Concurrency Issue with ASP.NET 2.0 GridViews/DetailsView/FormViews that Support Editing and/or Deleting and Whose View State is Disabled, for more information.)

Improving the UnitPrice Formatting

While the GridView example shown in Figure 6 works, the UnitPrice field is not formatted at all, which results in a price display that lacks any currency symbols and has four decimal places. To apply a currency formatting for the non-editable rows, just set the DataFormatString property of the UnitPrice BoundField to {0:c} and its HtmlEncode property to false.

Click here for larger image

Figure 7. Set the UnitPrice's DataFormatString and HtmlEncode properties accordingly. (Click on the picture for a larger image.)

With this change, the non-editable rows format the price as a currency; the edited row, however, still displays the value without the currency symbol and with four decimal places.

Click here for larger image

Figure 8. The non-editable rows are now formatted as currency values. (Click on the picture for a larger image.)

The formatting instructions specified in the DataFormatString property can be applied to the editing interface by setting the ApplyFormatInEditMode property of the BoundField to true (the default is false). Take a moment to set this property to true.

Click here for larger image

Figure 9. Set the UnitPrice BoundField's ApplyFormatInEditMode property to true. (Click on the picture for a larger image.)

With this change, the value of the UnitPrice that is displayed in the edited row also is formatted as a currency.

Click here for larger image

Figure 10. The edited row's UnitPrice value is now formatted as a currency. (Click on the picture for a larger image.)

However, updating a product with the currency symbol in the text box—such as $19.00—throws a FormatException. When the GridView attempts to assign the user-supplied values to the UpdateParameters collection of the ObjectDataSource, it is unable to convert the UnitPrice string "$19.00" into the decimal that is required by the parameter (see Figure 11). To remedy this, we can create an event handler for the RowUpdating event of the GridView and have it parse the user-supplied UnitPrice as a currency-formatted decimal.

The RowUpdating event of the GridView accepts as its second parameter an object of type GridViewUpdateEventArgs, which includes a NewValues dictionary as one of its properties that holds the user-supplied values that are ready to be assigned to the UpdateParameters collection of the ObjectDataSource. We can overwrite the existing UnitPrice value in the NewValues collection with a decimal value that is parsed by using the currency format with the following lines of code in the RowUpdating event handler:

protected void GridView1_RowUpdating(object sender, 
GridViewUpdateEventArgs e)

{

  if (e.NewValues["UnitPrice"] != null)

    e.NewValues["UnitPrice"] =

        decimal.Parse(e.NewValues["UnitPrice"].ToString(),

            System.Globalization.NumberStyles.Currency);

}

If the user has supplied a UnitPrice value (such as "$19.00"), this value is overwritten with the decimal value that is computed by Decimal.Parse, parsing the value as a currency. This will correctly parse the decimal in the event of any currency symbols, commas, decimal points, and so on, and uses the NumberStyles enumeration in the System.Globalization namespace.

Figure 11 shows both the problem that is caused by currency symbols in the user-supplied UnitPrice and how the RowUpdating event handler of the GridView can be utilized to parse such input correctly.

Click here for larger image

Figure 11. The edited row's UnitPrice value is now formatted as a currency. (Click on the picture for a larger image.)

Step 2: Prohibiting NULL UnitPrices

While the database is configured to allow NULL values in the UnitPrice column of the Products table, we might want to prevent users who visit this particular page from specifying a NULL UnitPrice value. That is, if a user fails to enter a UnitPrice value when editing a product row, instead of saving the results to the database, we want to display a message that informs the user that, through this page, any edited products must have a price specified.

The GridViewUpdateEventArgs object that is passed into the RowUpdating event handler of the GridView contains a Cancel property that, if set to true, terminates the updating process. Let's extend the RowUpdating event handler to set e.Cancel to true and display a message that explains why, if the UnitPrice value in the NewValues collection is null.

Start by adding a Label Web control to the page named MustProvideUnitPriceMessage. This Label control will be displayed if the user fails to specify a UnitPrice value when updating a product. Set the Text property of the Label to You must provide a price for the product. I've also created a new CSS class in Styles.css that is named Warning and has the following definition:

.Warning

{

    color: Red;

    font-style: italic;

    font-weight: bold;

    font-size: x-large;

}

Finally, set the CssClass property of the Label to Warning. At this point, the Designer should show the warning message in a red, bold, italic, extra-large font size above the GridView, as shown in Figure 12.

Click here for larger image

Figure 12. A label has been added above the GridView. (Click on the picture for a larger image.)

By default, this Label should be hidden, so set its Visible property to false in the Page_Load event handler:

protected void Page_Load(object sender, EventArgs e)

{

    MustProvideUnitPriceMessage.Visible = false;

}

If the user attempts to update a product without specifying the UnitPrice, we want to cancel the update and display the warning label. Augment the RowUpdating event handler of the GridView, as follows:

protected void GridView1_RowUpdating(object sender, 
GridViewUpdateEventArgs e)

{

    if (e.NewValues["UnitPrice"] != null)

    {

        e.NewValues["UnitPrice"] =

            decimal.Parse(e.NewValues["UnitPrice"].ToString(),

                System.Globalization.NumberStyles.Currency);

    }

    else

    {

        // Show the Label

        MustProvideUnitPriceMessage.Visible = true;



        // Cancel the update

        e.Cancel = true;

    }

}

If a user attempts to save a product without specifying a price, the update is cancelled and a helpful message is displayed. While the database (and business logic) allow for NULL UnitPrices, this particular ASP.NET page does not.

Click here for larger image

Figure 13. A user cannot leave UnitPrice blank. (Click on the picture for a larger image.)

So far, we have seen how to use the RowUpdating event of the GridView to programmatically alter the parameter values assigned to the UpdateParameters collection of the ObjectDataSource, as well as how to cancel the updating process altogether. These concepts carry over to the DetailsView and FormView controls and apply also to inserting and deleting.

These tasks can also be done at the ObjectDataSource level through event handlers for its Inserting, Updating, and Deleting events. These events fire before the associated method of the underlying object is invoked, and they provide a last-chance opportunity to modify the input parameters collection or cancel the operation outright. The event handlers for these three events are passed an object of type ObjectDataSourceMethodEventArgs that has two properties of interest:

  • Cancel, which, if set to true, cancels the operation being performed
  • InputParameters, which is the collection of InsertParameters, UpdateParameters, or DeleteParameters, depending on whether the event handler is for the Inserting, Updating, or Deleting event

To illustrate working with the parameter values at the ObjectDataSource level, let's include a DetailsView in our page that allows the users to add a new product. This DetailsView will be used to provide an interface for adding a new product to the database quickly. To keep a consistent user interface when adding a new product, let's allow the user to enter values for the ProductName and UnitPrice fields only. By default, those values that aren't supplied in the inserting interface of the DetailsView will be set to a NULL database value. However, we can use the Inserting event of the ObjectDataSource to inject different default values, as we'll see shortly.

Step 3: Providing an Interface to Add New Products

Drag a DetailsView from the Toolbox onto the Designer above the GridView, remove its Height and Width properties, and bind it to the ObjectDataSource that is already present on the page. This will add a BoundField or CheckBoxField for each of the product's fields. Because we want to use this DetailsView to add new products, we must check the Enable Inserting option from the smart tag. However, there's no such option, because the Insert() method of the ObjectDataSource is not mapped to a method in the ProductsBLL class; recall that we set this mapping to (None) when configuring the data source (see Figure 3).

To configure the ObjectDataSource, select the Configure Data Source link from its smart tag, which launches the wizard. The first screen allows you to change the underlying object to which the ObjectDataSource is bound; leave it set to ProductsBLL. The next screen lists the mappings from the methods of the ObjectDataSource to those of the underlying object. Although we explicitly indicated that the Insert() and Delete() methods should not be mapped to any methods, if you go to the INSERT and DELETE tabs, you'll see that a mapping is there. This is because the AddProduct and DeleteProduct methods of the ProductsBLL use the DataObjectMethodAttribute attribute to indicate that they are the default methods for Insert() and Delete(), respectively. Hence, the ObjectDataSource wizard selects these each time that you run the wizard, unless there's some other value that is specified explicitly.

Leave the Insert() method pointing to the AddProduct method, but again set the drop-down list of the DELETE tab to (None).

Click here for larger image

Figure 14. Set the INSERT tab's drop-down list to the AddProduct method. (Click on the picture for a larger image.)

Click here for larger image

Figure 15. Set the DELETE tab's drop-down list to (None). (Click on the picture for a larger image.)

After you have made these changes, the declarative syntax of the ObjectDataSource will be expanded to include an InsertParameters collection, as shown here:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"

    SelectMethod="GetProducts" TypeName="ProductsBLL"

    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"

    InsertMethod="AddProduct" 
OldValuesParameterFormatString="original_{0}">

    <UpdateParameters>

        <asp:Parameter Name="productName" Type="String" />

        <asp:Parameter Name="unitPrice" Type="Decimal" />

        <asp:Parameter Name="productID" Type="Int32" />

    </UpdateParameters>

    <InsertParameters>

        <asp:Parameter Name="productName" Type="String" />

        <asp:Parameter Name="supplierID" Type="Int32" />

        <asp:Parameter Name="categoryID" Type="Int32" />

        <asp:Parameter Name="quantityPerUnit" Type="String" />

        <asp:Parameter Name="unitPrice" Type="Decimal" />

        <asp:Parameter Name="unitsInStock" Type="Int16" />

        <asp:Parameter Name="unitsOnOrder" Type="Int16" />

        <asp:Parameter Name="reorderLevel" Type="Int16" />

        <asp:Parameter Name="discontinued" Type="Boolean" />

    </InsertParameters>

</asp:ObjectDataSource>

Rerunning the wizard added back the OldValuesParameterFormatString property. Take a moment to clear this property by either setting it to the default value ({0}) or removing it altogether from the declarative syntax.

With the ObjectDataSource providing inserting capabilities, the DetailsView's smart tag will now include the Enable Inserting check box; return to the Designer and check this option. Next, pare down the DetailsView, so that it has only two BoundFields—ProductName and UnitPrice—and the CommandField. At this point, the declarative syntax of the DetailsView should look like the following:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"

    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">

    <Fields>

        <asp:BoundField DataField="ProductName"

          HeaderText="ProductName" SortExpression="ProductName" />

        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"

          SortExpression="UnitPrice" />

        <asp:CommandField ShowInsertButton="True" />

    </Fields>

</asp:DetailsView>

Figure 16 shows this page when viewed through a browser at this point. As you can see, the DetailsView lists the name and price of the first product (Chai). What we want, however, is an inserting interface that provides a means for the user to add a new product to the database quickly.

Click here for larger image

Figure 16. The DetailsView is currently rendered in read-only mode. (Click on the picture for a larger image.)

In order to show the DetailsView in its inserting mode, we must set the DefaultMode property to Inserting. This renders the DetailsView in insert mode when first visited, and keeps it there after inserting a new record. As Figure 17 shows, such a DetailsView provides a quick interface for adding a new record.

Click here for larger image

Figure 17. The DetailsView provides an interface for adding a new product quickly. (Click on the picture for a larger image.)

When the user enters a product name and price—such as "Acme Water" and "1.99", as in Figure 17—and clicks Insert, a postback ensues and the inserting workflow commences, which culminates in a new product record being added to the database. The DetailsView maintains its inserting interface and the GridView is automatically rebound to its data source in order to include the new product, as shown in Figure 18.

Figure 18. The product Acme Water has been added to the database.

While the GridView in Figure 18 doesn't show it, the product fields that are lacking from the DetailsView interface—CategoryID, SupplierID, QuantityPerUnit, and so on—are assigned NULL database values. You can see this by performing the following steps:

  1. Go to the Server Explorer in Visual Studio.
  2. Expand the NORTHWND.MDF database node.
  3. Right-click on the Products database table node.
  4. Select Show Table Data.

This procedure will list all of the records in the Products table. As Figure 19 shows, all of the columns of our new product—other than ProductID, ProductName, and UnitPrice—have NULL values.

Click here for larger image

Figure 19. The product fields that are not provided in the DetailsView are assigned NULL values. (Click on the picture for a larger image.)

We might want to provide a default value other than NULL for one or more of these column values, either because NULL isn't the best default option or because the database column itself doesn't allow NULLs. To accomplish this, we can programmatically set the values of the parameters of the InputParameters collection of the DetailsView. This assignment can be done in either the event handler for the ItemInserting event of the DetailsView or the Inserting event of the ObjectDataSource. Because we've already looked at using the pre-level and post-level events at the data Web control level, let's explore this time using the ObjectDataSource's events.

Step 4: Assigning Values to the CategoryID and SupplierID Parameters

For this tutorial, let's imagine that for our application, when adding a new product through this interface, it should be assigned a CategoryID and SupplierID value of 1. As mentioned earlier, the ObjectDataSource has a pair of pre-level and post-level events that fire during the data-modification process. When its Insert() method is invoked, the ObjectDataSource first raises its Inserting event, then calls the method to which its Insert() method has been mapped, and finally raises the Inserted event. The Inserting event handler affords us one last opportunity to tweak the input parameters or cancel the operation outright.

Note In a real-world application, you would likely want either to let users specify the category and supplier or to pick this value for them, based on some criteria or business logic (instead of blindly selecting an ID of 1). Regardless, the example illustrates how to programmatically set the value of an input parameter from the pre-level event of the ObjectDataSource.

Take a moment to create an event handler for the Inserting event of the ObjectDataSource. Notice that the event handler's second input parameter is an object of type ObjectDataSourceMethodEventArgs, which has a property to access the parameters collection (InputParameters) and a property to cancel the operation (Cancel).

protected void ObjectDataSource1_Inserting

    (object sender, ObjectDataSourceMethodEventArgs e)

{



}

At this point, the InputParameters property contains the InsertParameters collection of the ObjectDataSource with the values assigned from the DetailsView. To change the value of one of these parameters, just use e.InputParameters["paramName"] = value. Therefore, to set the CategoryID and SupplierID to values of 1, adjust the Inserting event handler to look like the following:

protected void ObjectDataSource1_Inserting

    (object sender, ObjectDataSourceMethodEventArgs e)

{

    e.InputParameters["CategoryID"] = 1;

    e.InputParameters["SupplierID"] = 1;

}

This time, when adding a new product—such as Acme Soda—the CategoryID and SupplierID columns of the new product are set to 1 (see Figure 20).

Click here for larger image

Figure 20. New products now have their CategoryID and SupplierID values set to 1. (Click on the picture for a larger image.)

Conclusion

During the editing, inserting, and deleting processes, both the data Web control and the ObjectDataSource proceed through a number of pre-level and post-level events. In this tutorial, we examined the pre-level events and saw how to use these to customize the input parameters or cancel the data-modification operation altogether—both from the data Web control and the ObjectDataSource's events. In the next tutorial, we'll look at how to create and use event handlers for the post-level events.

Happy programming!

 

About the author

Scott Mitchell, author of six ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott works as an independent consultant, trainer, and writer, and he recently completed his latest book, Sams Teach Yourself ASP.NET 2.0 in 24 Hours. He can be reached at mitchell@4guysfromrolla.com or via his blog, which can be found at http://ScottOnWriting.NET.

Special Thanks

This tutorial series was reviewed by many helpful reviewers. Lead reviewers for this tutorial include Jackie Goor and Liz Shulok. Interested in reviewing my upcoming MSDN articles? If so, drop me a line at mitchell@4GuysFromRolla.com.

© Microsoft Corporation. All rights reserved.