在ASP.NET 2.0中操作数据之三十八:处理BLL和DAL的异(2)

  UpdateCommand事件处理稍微麻烦一点。它需要从DataKey集合里读取被编辑的product的ProductID,和EditItemTemplate里的TextBox里的product的name和price,然后调用ProductsBLL类的UpdateProduct方法,最后返回到DataList编辑前的状态。

  我们在这里使用 在DataList里编辑和删除数据概述 里的UpdateCommand事件处理代码。

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e) { // Read in the ProductID from the DataKeys collection int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]); // Read in the product name and price values TextBox productName = (TextBox)e.Item.FindControl("ProductName"); TextBox unitPrice = (TextBox)e.Item.FindControl("UnitPrice"); string productNameValue = null; if (productName.Text.Trim().Length > 0) productNameValue = productName.Text.Trim(); decimal? unitPriceValue = null; if (unitPrice.Text.Trim().Length > 0) unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(), System.Globalization.NumberStyles.Currency); // Call the ProductsBLL's UpdateProduct method... ProductsBLL productsAPI = new ProductsBLL(); productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID); // Revert the DataList back to its pre-editing state Products.EditItemIndex = -1; Products.DataBind(); }

  在有非法输入的时候— 可能是不正确的price格式,比如“-$5.00”,或者忽略了product的name— 就会引起异常。由于UpdateCommand事件处理还没有处理异常,页面会出现ASP.NET运行时错误。见图3。

/uploads/allimg/200612/1J210IJ_0.png


图 3: 未处理异常发生时,用户会看到这样的错误页面

第二步: 在UpdateCommand Event Handler里处理异常

  更新流程中,异常可能发生在UpdateCommand事件处理,或BLL或DAL里。比如,如果用户输入了一个“太贵”的价格,UpdateCommand 事件处理里的Decimal.Parse 会抛出FormatException 异常。如果用户忽略了product的name或者price是一个负数,DAL会抛出异常。

当异常发生时,我们希望显示自己定义的信息。添加一个ID为ExceptionDetails的Label控件到页面上,通过设置CssClass属性为Warning CSS类来将Text设置为红色,特大,加粗的意大利字体。这个类在Styles.css文件里定义。

  异常发生时,我们只希望这个 Label显示一次。也就是说,在后面postback的时候,Label的警告信息需要隐藏起来。这个可以通过清除Label的Text属性或者将Visible属性设为False(在Page_Load里)(如我们在在ASP.NET页面中处理BLL/DAL层的异常 里做的那样)或者禁用Label的view state来实现。我们这里用后一种方法。

<asp:Label EnableViewState="False" CssClass="Warning" runat="server" />

  异常发生时,我们将异常的信息显示在Label的Text属性上。由于view state被禁用了,后面再postback的话,Text属性会自动的丢失,回到缺省值(空字符串),这样就隐藏了警告信息。

  异常发生时将信息显示在页面上,我们需要在UpdateCommand事件处理里添加Try....Catch块。Try的那部分包含可能抛出异常的代码,Catch部分包含当出现异常时需要执行的代码。更多的Try..Catch块信息参考Exception Handling Fundamentals 。

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e) { // Handle any exceptions raised during the editing process try { // Read in the ProductID from the DataKeys collection int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]); ... Some code omitted for brevity ... } catch (Exception ex) { // TODO: Display information about the exception in ExceptionDetails } }

  无论Try块里抛出何种类型的异常,Catch块的代码都会执行。抛出异常的类型—DbException, NoNullAllowedException, ArgumentException等 — 取决于第一个错误。如果是数据库级别的问题,会抛出DbException 。如果是UnitPrice, UnitsInStock, UnitsOnOrder, 或ReorderLevel 字段有非法值,会抛出ArgumentException (我们在ProductsDataTable里已经添加过验证字段值的代码,见创建一个业务逻辑层 )

  我们可以根据捕捉到的异常的类型来为用户提供更好的帮助。下面的代码— 和在ASP.NET页面中处理BLL/DAL层的异常 中基本上一样— 提供了这个功能:

private void DisplayExceptionDetails(Exception ex) { // Display a user-friendly message ExceptionDetails.Text = "There was a problem updating the product. "; if (ex is System.Data.Common.DbException) ExceptionDetails.Text += "Our database is currently experiencing problems. Please try again later."; else if (ex is NoNullAllowedException) ExceptionDetails.Text += "There are one or more required fields that are missing."; else if (ex is ArgumentException) { string paramName = ((ArgumentException)ex).ParamName; ExceptionDetails.Text += string.Concat("The ", paramName, " value is illegal."); } else if (ex is ApplicationException) ExceptionDetails.Text += ex.Message; }        

  最后仅仅只需要调用DisplayExceptionDetails方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwypx.html