检查与插入、更新和删除操作有关的事件 (C#)
在本教程中,我们将检查 ASP.NET 数据 Web 控件的插入、更新或删除操作之前、期间和之后发生的事件。 我们还将了解如何自定义编辑界面,以仅更新产品字段的子集。
简介
使用 GridView、DetailsView 或 FormView 控件的内置插入、编辑或删除功能时,当最终用户完成添加新记录或更新或删除现有记录的过程时,会出现各种步骤。 如 上一教程中所述,在 GridView 中编辑行时,“编辑”按钮将替换为“更新”和“取消”按钮,而 BoundField 将变为 TextBox。 最终用户更新数据并单击“更新”后,对回发执行以下步骤:
- GridView 通过
DataKeyNames
属性) 以及用户输入的值,使用编辑记录的唯一标识字段 () (填充其 ObjectDataSourceUpdateParameters
的 - GridView 调用其 ObjectDataSource 的
Update()
方法,后者又在上一教程中调用基础对象 (ProductsDAL.UpdateProduct
中的相应方法) - 基础数据(现在包括更新的更改)将反弹到 GridView
在这一系列步骤中,会触发大量事件,使我们能够创建事件处理程序以根据需要添加自定义逻辑。 例如,在步骤 1 之前,GridView 的事件 RowUpdating
会触发。 此时,如果存在某些验证错误,我们可以取消更新请求。 Update()
调用 方法时,将触发 ObjectDataSource 的事件Updating
,从而提供添加或自定义任何 UpdateParameters
的值的机会。 在 ObjectDataSource 的基础对象的 方法完成执行后,将引发 ObjectDataSource 的 Updated
事件。 事件的事件处理程序 Updated
可以检查有关更新操作的详细信息,例如受影响的行数以及是否发生异常。 最后,在步骤 2 之后,GridView RowUpdated
的事件将触发;此事件的事件处理程序可以检查有关刚刚执行的更新操作的其他信息。
图 1 描述了更新 GridView 时的这一系列事件和步骤。 图 1 中的事件模式对于使用 GridView 进行更新并不是唯一的。 插入、更新或删除 GridView、DetailsView 或 FormView 中的数据会为数据 Web 控件和 ObjectDataSource 引发相同的前级和后级事件序列。
图 1:在 GridView 中更新数据时触发一系列前事件和事后事件 (单击以查看全尺寸图像)
在本教程中,我们将研究如何使用这些事件来扩展 ASP.NET 数据 Web 控件的内置插入、更新和删除功能。 我们还将了解如何自定义编辑界面,以仅更新产品字段的子集。
步骤 1:更新产品和ProductName
UnitPrice
字段
在上一教程的编辑界面中,必须包含 所有 非只读产品字段。 如果在更新数据时要从 GridView 中删除字段, QuantityPerUnit
则数据 Web 控件不会设置 ObjectDataSource 的值 QuantityPerUnit
UpdateParameters
。 然后,ObjectDataSource 会将值UpdateProduct
传递到null
业务逻辑层 (BLL) 方法中,该方法会将已编辑的数据库记录的QuantityPerUnit
列更改为NULL
值。 同样,如果从编辑界面中删除必填字段(如 ProductName
),更新将失败并出现“列'ProductName'不允许 null”异常。 之所以出现此行为,是因为 ObjectDataSource 配置为调用 ProductsBLL
类的 UpdateProduct
方法,这需要每个产品字段的输入参数。 因此,ObjectDataSource 的 UpdateParameters
集合包含方法的每个输入参数的参数。
如果我们想要提供允许最终用户仅更新字段子集的数据 Web 控件,则需要以编程方式在 ObjectDataSource 的Updating
事件处理程序中设置缺失UpdateParameters
值,或者创建并调用只需要字段子集的 BLL 方法。 让我们探讨后一种方法。
具体来说,让我们创建一个页面,该页面仅在 ProductName
可编辑的 GridView 中显示 和 UnitPrice
字段。 此 GridView 的编辑界面将仅允许用户更新显示的两个字段和 ProductName
UnitPrice
。 由于此编辑接口仅提供产品字段的子集,因此我们需要创建使用现有 BLL 方法的 UpdateProduct
ObjectDataSource,并在其 Updating
事件处理程序中以编程方式设置缺少的产品字段值,或者我们需要创建一个新的 BLL 方法,该方法仅需要 GridView 中定义的字段子集。 对于本教程,我们将使用后一个选项并创建 方法的 UpdateProduct
重载,该方法只接受三个输入参数: productName
、 unitPrice
和 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;
}
与原始 UpdateProduct
方法一样,此重载首先检查数据库中是否存在具有指定 ProductID
的 的产品。 如果不是,则返回 false
,指示更新产品信息的请求失败。 否则,它会相应地更新现有产品记录的 ProductName
和 UnitPrice
字段,并通过调用 TableAdapter 的 Update()
方法提交更新,并 ProductsRow
传入 实例。
在类中添加此内容 ProductsBLL
后,我们可以创建简化的 GridView 接口。 DataModificationEvents.aspx
打开 文件夹中的 EditInsertDelete
,并将 GridView 添加到页面。 创建一个新的 ObjectDataSource,并将其配置为使用 ProductsBLL
类及其 Select()
方法映射到 GetProducts
Update()
UpdateProduct
仅 productName
采用 、 unitPrice
和 productID
输入参数的重载。 图 2 显示了将 ObjectDataSource 的 Update()
方法映射到 ProductsBLL
类的新 UpdateProduct
方法重载时的“创建数据源”向导。
图 2:将 ObjectDataSource 的 Update()
方法映射到“新建 UpdateProduct
重载” (单击以查看全尺寸图像)
由于我们的示例最初只需要编辑数据的功能,但不需要插入或删除记录,因此请花点时间通过转到“插入”和“删除”选项卡并从下拉列表中选择“ (无) ”,明确指示不应将 ObjectDataSource Insert()
的 和 Delete()
方法映射到类的任何 ProductsBLL
方法。
图 3:从“插入”和“删除”选项卡的“Drop-Down 列表中选择” (无) (单击以查看全尺寸图像)
完成此向导后,检查 GridView 智能标记中的“启用编辑”复选框。
完成“创建数据源”向导并将其绑定到 GridView 后,Visual Studio 为这两个控件创建了声明性语法。 转到“源”视图以检查 ObjectDataSource 的声明性标记,如下所示:
<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>
由于 ObjectDataSource 的 Insert()
和 Delete()
方法没有映射,因此没有 InsertParameters
或 DeleteParameters
部分。 此外,由于 Update()
方法映射到 UpdateProduct
仅接受三个输入参数的方法重载,因此节 UpdateParameters
只有三 Parameter
个实例。
请注意,ObjectDataSource 的 OldValuesParameterFormatString
属性设置为 original_{0}
。 使用“配置数据源”向导时,Visual Studio 会自动设置此属性。 但是,由于 BLL 方法不希望传入原始 ProductID
值,因此请从 ObjectDataSource 的声明性语法中完全删除此属性赋值。
注意
如果只是从“设计”视图中的属性窗口中清除OldValuesParameterFormatString
属性值,则 属性仍将存在于声明性语法中,但将设置为空字符串。 从声明性语法中完全删除 属性,或者从属性窗口将 值设置为默认值 {0}
。
虽然 ObjectDataSource 仅 UpdateParameters
包含产品名称、价格和 ID,但 Visual Studio 已在 GridView 中为每个产品的字段添加了 BoundField 或 CheckBoxField。
图 4:GridView 包含每个产品的字段的 BoundField 或 CheckBoxField (单击以查看全尺寸图像)
当最终用户编辑产品并单击其“更新”按钮时,GridView 会枚举那些非只读字段。 然后,它将 ObjectDataSource UpdateParameters
集合中相应参数的值设置为用户输入的值。 如果没有相应的参数,GridView 会将一个参数添加到集合中。 因此,如果我们的 GridView 包含所有产品字段的 BoundFields 和 CheckBoxFields,则 ObjectDataSource 最终将调用 UpdateProduct
采用所有这些参数的重载,尽管 ObjectDataSource 的声明性标记仅指定三个输入参数 (请参阅图 5) 。 同样,如果 GridView 中的非只读产品字段组合与重载的输入参数 UpdateProduct
不对应,则尝试更新时将引发异常。
图 5:GridView 将向 ObjectDataSource 的 UpdateParameters
集合添加参数 (单击以查看全尺寸图像)
若要确保 ObjectDataSource 调用 UpdateProduct
仅接受产品名称、价格和 ID 的重载,我们需要将 GridView 限制为仅 ProductName
包含 和 UnitPrice
的可编辑字段。 这可以通过删除其他 BoundFields 和 CheckBoxFields 来实现,方法是将其他字段的 ReadOnly
属性设置为 true
,或者通过两者的某种组合来实现。 对于本教程,我们只需删除除 和 UnitPrice
BoundFields 之外ProductName
的所有 GridView 字段,然后 GridView 的声明性标记将如下所示:
<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>
尽管 UpdateProduct
重载需要三个输入参数,但 GridView 中只有两个 BoundField。 这是因为输入 productID
参数是主键值,并通过已编辑行的 DataKeyNames
属性的值传入。
我们的 GridView 以及 UpdateProduct
重载允许用户仅编辑产品的名称和价格,而不会丢失任何其他产品字段。
图 6:界面仅允许编辑产品名称和价格 (单击以查看全尺寸图像)
注意
如上一教程中所述,在默认行为) (启用 GridView 视图状态至关重要。 如果将 GridView 的 EnableViewState
属性设置为 false
,则存在并发用户无意中删除或编辑记录的风险。
UnitPrice
改进格式设置
虽然图 6 中显示的 GridView 示例有效,但 UnitPrice
该字段根本没有设置格式,导致价格显示缺少任何货币符号,并且具有四个小数位数。 若要为不可编辑的行应用货币格式设置,只需将 UnitPrice
BoundField 的 DataFormatString
属性设置为 {0:c}
,将其 HtmlEncode
属性设置为 false
。
图 7:相应地设置 UnitPrice
的 DataFormatString
和 HtmlEncode
属性 (单击 以查看全尺寸图像)
进行此更改后,不可编辑的行将价格格式设置为货币;但是,编辑的行仍然显示没有货币符号和四个小数位数的值。
图 8:不可编辑的行现在格式化为货币值 (单击以查看全尺寸图像)
通过将 BoundField 的 ApplyFormatInEditMode
属性true
设置为 (默认值false
为) ,可以将 属性中指定的DataFormatString
格式设置指令应用于编辑界面。 花点时间将此属性设置为 true
。
图 9:将 UnitPrice
BoundField 的 ApplyFormatInEditMode
属性设置为 true
(单击 以查看全尺寸图像)
进行此更改后,在编辑的行中显示的 值 UnitPrice
也会格式化为货币。
图 10:编辑的 UnitPrice
行的值现在格式化为货币 (单击以查看全尺寸图像)
但是,使用文本框中的货币符号(如 $19.00)更新产品会 FormatException
引发 。 当 GridView 尝试将用户提供的值分配给 ObjectDataSource 的UpdateParameters
集合时,无法将字符串“$19.00”转换为UnitPrice
decimal
参数所需的 (请参阅图 11) 。 为了解决此问题,我们可以为 GridView 的事件 RowUpdating
创建事件处理程序,并让其分析用户提供的 UnitPrice
货币格式 decimal
。
GridView 的 RowUpdating
事件接受 GridViewUpdateEventArgs 类型的对象作为其第二个参数,该对象包含一个 NewValues
字典作为其属性之一,该属性保存用户提供的值已准备好分配给 ObjectDataSource 的 UpdateParameters
集合。 可以使用使用货币格式分析的十进制值覆盖集合中的NewValues
现有UnitPrice
值,并在 事件处理程序中RowUpdating
使用以下代码行:
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);
}
如果用户提供了 UnitPrice
(的值(如“$19.00”) ),则此值将被 Decimal.Parse 计算的十进制值覆盖,并将该值分析为货币。 这将在出现任何货币符号、逗号、小数点等的情况下正确分析小数,并使用 System.Globalization 命名空间中的 NumberStyles 枚举。
图 11 显示了用户提供的 UnitPrice
中货币符号引起的问题,以及如何利用 GridView 的 RowUpdating
事件处理程序来正确分析此类输入。
图 11:编辑的 UnitPrice
行的值现在格式化为货币 (单击以查看全尺寸图像)
步骤 2:禁止NULL UnitPrices
虽然数据库配置为允许NULL
表的 UnitPrice
列中的值Products
,但我们可能需要阻止访问此特定页面的用户指定NULL
UnitPrice
值。 也就是说,如果用户在编辑产品行时未能输入 UnitPrice
值,而不是将结果保存到数据库,我们希望显示一条消息,告知用户,通过此页面,任何已编辑的产品都必须指定价格。
GridViewUpdateEventArgs
传递到 GridView 的事件处理程序中的 RowUpdating
对象包含一个Cancel
属性,如果设置为 true
,则终止更新过程。 让我们扩展RowUpdating
事件处理程序以将 设置为 true
e.Cancel
,并显示一条消息,说明集合中的NewValues
值为 时UnitPrice
为何为 null
。
首先,将标签 Web 控件添加到名为 MustProvideUnitPriceMessage
的页面。 如果用户在更新产品时未能指定 UnitPrice
值,将显示此标签控件。 将 Label 的 Text
属性设置为“必须提供产品的价格”。我还使用以下定义在 中 Styles.css
创建了名为 Warning
的新 CSS 类:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
最后,将 Label 的 CssClass
属性设置为 Warning
。 此时,Designer应在 GridView 上方显示红色、粗体、斜体、特大字号的警告消息,如图 12 所示。
图 12:GridView 上方添加了标签 (单击以查看全尺寸图像)
默认情况下,应隐藏此 Label,因此请在事件处理程序中将其Visible
属性设置为 false
:Page_Load
protected void Page_Load(object sender, EventArgs e)
{
MustProvideUnitPriceMessage.Visible = false;
}
如果用户尝试在未指定 UnitPrice
的情况下更新产品,我们希望取消更新并显示警告标签。 按如下所示扩充 GridView 的 RowUpdating
事件处理程序:
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;
}
}
如果用户尝试在未指定价格的情况下保存产品,则会取消更新并显示一条有用的消息。 虽然数据库 (和业务逻辑) 允许 NULL
UnitPrice
,但此特定 ASP.NET 页却不允许。
图 13:用户不能留 UnitPrice
空 (单击以查看全尺寸图像)
到目前为止,我们已经了解了如何使用 GridView 的 RowUpdating
事件以编程方式更改分配给 ObjectDataSource 集合的参数 UpdateParameters
值,以及如何完全取消更新过程。 这些概念延续到 DetailsView 和 FormView 控件,也适用于插入和删除。
这些任务也可以在 ObjectDataSource 级别通过其 、 Updating
和 Deleting
事件的事件处理程序Inserting
来完成。 这些事件在调用基础对象的关联方法之前触发,并提供修改输入参数集合或直接取消操作的最后机会。 这三个事件的事件处理程序传递给 ObjectDataSourceMethodEventArgs 类型的对象,该对象具有两个相关属性:
- 取消,如果设置为
true
,则取消正在执行的操作 - InputParameters,它是 、
UpdateParameters
或DeleteParameters
的InsertParameters
集合,具体取决于事件处理程序是否适用于Inserting
、Updating
或Deleting
事件
为了说明如何在 ObjectDataSource 级别使用参数值,让我们在页面中包括一个 DetailsView,允许用户添加新产品。 此 DetailsView 将用于提供一个界面,用于快速将新产品添加到数据库。 为了在添加新产品时保持一致的用户界面,允许用户仅输入 ProductName
和 UnitPrice
字段的值。 默认情况下,DetailsView 的插入接口中未提供的那些值将设置为 NULL
数据库值。 但是,我们可以使用 ObjectDataSource 的 Inserting
事件注入不同的默认值,我们稍后将看到。
步骤 3:提供添加新产品的接口
将 DetailsView 从“工具箱”拖到 GridView 上方的Designer上,清除其 Height
和 Width
属性,并将其绑定到页面上已存在的 ObjectDataSource。 这将为每个产品的字段添加 BoundField 或 CheckBoxField。 由于我们想要使用此 DetailsView 添加新产品,因此我们需要从智能标记检查 Enable Inserting 选项;但是,没有此类选项,因为 ObjectDataSource 的 Insert()
方法未映射到类中ProductsBLL
的方法, (回想一下,在配置数据源时将此映射设置为“ (None”) ,请参阅图 3) 。
若要配置 ObjectDataSource,请从其智能标记中选择“配置数据源”链接,启动向导。 第一个屏幕允许更改 ObjectDataSource 绑定到的基础对象;将其设置为 ProductsBLL
。 下一个屏幕列出了从 ObjectDataSource 的 方法到基础对象的 的映射。 尽管我们明确指出 Insert()
不应将 和 Delete()
方法映射到任何方法,但如果转到“插入”和“删除”选项卡,你将看到存在映射。 这是因为 的 ProductsBLL
和 方法使用 DataObjectMethodAttribute
属性来指示它们分别是 和 Delete()
的默认方法Insert()
。DeleteProduct
AddProduct
因此,每次运行向导时,ObjectDataSource 向导都会选择这些值,除非显式指定了其他值。
Insert()
保留方法指向 AddProduct
方法,但再次将 DELETE 选项卡的下拉列表设置为 (none) 。
图 14:将“INSERT”选项卡的“Drop-Down 列表”设置为 AddProduct
“方法 (单击以查看全尺寸图像)
图 15:将“删除”选项卡的“Drop-Down 列表”设置为“ (无”) (单击以查看全尺寸图像)
进行这些更改后,ObjectDataSource 的声明性语法将展开以包含集合 InsertParameters
,如下所示:
<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>
重新运行添加回 属性的 OldValuesParameterFormatString
向导。 请花点时间将其设置为默认值, ({0}
) 或将其从声明性语法中完全删除。
随着 ObjectDataSource 提供插入功能,DetailsView 的智能标记现在将包括“启用插入”复选框;返回到Designer并检查此选项。 接下来,请向下分析 DetailsView,使其只有两个 BoundField - ProductName
和 UnitPrice
- 以及 CommandField。 此时,DetailsView 的声明性语法应如下所示:
<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>
图 16 显示了此时通过浏览器查看的此页面。 如您所看到的,DetailsView 列出了第一个产品的名称和价格 (Chai) 。 但是,我们想要的是一个插入界面,它为用户提供了一种将新产品快速添加到数据库的方法。
图 16:DetailsView 当前以 Read-Only 模式呈现 (单击以查看全尺寸图像)
为了在插入模式下显示 DetailsView,需要将 DefaultMode
属性设置为 Inserting
。 这会在首次访问时以插入模式呈现 DetailsView,并在插入新记录后将其保留在那里。 如图 17 所示,此类 DetailsView 提供了用于添加新记录的快速界面。
图 17:DetailsView 提供用于快速添加新产品的界面 (单击以查看全尺寸图像)
当用户输入产品名称和价格 ((如“Acme Water”和 1.99)时,如图 17) 并单击“插入”,随后将进行回发,插入工作流开始,最终会向数据库添加新的产品记录。 DetailsView 保留其插入接口,GridView 会自动重新绑定到其数据源以包含新产品,如图 18 所示。
图 18:产品“Acme Water”已添加到数据库
虽然图 18 中的 GridView 未显示,但 DetailsView 接口 CategoryID
、 SupplierID
、 QuantityPerUnit
等中缺少的产品字段将分配 NULL
数据库值。 可以通过执行以下步骤来查看此情况:
- 转到 Visual Studio 中的服务器资源管理器
- 展开
NORTHWND.MDF
数据库节点 - 右键单击
Products
数据库表节点 - 选择“显示表数据”
这将列出表中的所有 Products
记录。 如图 19 所示,除 、 ProductName
和 UnitPrice
以外的ProductID
所有新产品列都具有NULL
值。
图 19:“详细信息”视图中未提供的产品字段分配 NULL
值 (单击以查看全尺寸图像)
我们可能希望为其中一个或多个列值提供默认值, NULL
因为 NULL
不是最佳默认选项,或者数据库列本身不允许 NULL
。 为此,我们可以以编程方式设置 DetailsView InputParameters
集合的参数值。 可以在 DetailsView 的 事件或 ObjectDataSource Inserting
事件的ItemInserting
事件处理程序中完成此分配。 由于我们已经了解了在数据 Web 控件级别使用前级和级别后事件,因此这次让我们探讨如何使用 ObjectDataSource 的事件。
步骤 4:为 和SupplierID
参数赋值CategoryID
在本教程中,假设应用程序在通过此接口添加新产品时,应为其分配一个 CategoryID
,值为 SupplierID
1。 如前所述,ObjectDataSource 具有一对在数据修改过程中触发的级别前和后级别事件。 调用其 Insert()
方法时,ObjectDataSource 首先引发其 Inserting
事件,然后调用其 Insert()
方法已映射到的方法,最后引发事件 Inserted
。 事件处理程序 Inserting
为我们提供了最后一次调整输入参数或直接取消操作的机会。
注意
在实际应用程序中,你可能希望让用户指定类别和供应商,或者根据某些条件或业务逻辑 (为他们选取此值,而不是盲目选择 ID 1) 。 无论如何,此示例演示了如何以编程方式设置 ObjectDataSource 的预级别事件中的输入参数的值。
花点时间为 ObjectDataSource 的 Inserting
事件创建事件处理程序。 请注意,事件处理程序的第二个输入参数是 类型的 ObjectDataSourceMethodEventArgs
对象,该对象具有用于访问参数集合 (InputParameters
) 的属性,以及用于取消操作 (Cancel
) 的属性。
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
}
此时, InputParameters
属性包含 ObjectDataSource 的 InsertParameters
集合,其中包含从 DetailsView 分配的值。 若要更改其中一个参数的值,只需使用: e.InputParameters["paramName"] = value
。 因此,若要将 CategoryID
和 SupplierID
设置为 1 的值,请 Inserting
调整事件处理程序,如下所示:
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["CategoryID"] = 1;
e.InputParameters["SupplierID"] = 1;
}
此时,添加新产品 ((如 Acme Soda) )时, CategoryID
新产品的 和 SupplierID
列设置为 1 (见图 20) 。
图 20:新产品现在将其 CategoryID
和 SupplierID
值设置为 1 (单击以查看全尺寸图像)
总结
在编辑、插入和删除过程中,数据 Web 控件和 ObjectDataSource 都继续执行许多前级和后级事件。 在本教程中,我们检查了预级别事件,并了解了如何使用这些事件从数据 Web 控件和 ObjectDataSource 的事件中自定义输入参数或完全取消数据修改操作。 在下一教程中,我们将介绍如何为后级别事件创建和使用事件处理程序。
编程愉快!
关于作者
Scott Mitchell 是七本 ASP/ASP.NET 书籍的作者, 4GuysFromRolla.com 的创始人,自 1998 年以来一直从事 Microsoft Web 技术工作。 Scott 担任独立顾问、培训师和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0自学。 可以在 上联系 mitchell@4GuysFromRolla.com他, 也可以通过他的博客联系到他,该博客可在 http://ScottOnWriting.NET中找到。
特别感谢
本教程系列由许多有用的审阅者查看。 本教程的主要审阅者是 Jackie Goor 和 Liz Shulok。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处放置一行 mitchell@4GuysFromRolla.com。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈