【问题标题】:Gracefully returning to a .aspx.cs file from a catch from another class从另一个类的捕获中优雅地返回到 .aspx.cs 文件
【发布时间】:2012-01-19 02:59:12
【问题描述】:

我有一个 Web 项目,它有一个名为 editemployee.aspx 的页面。后面的代码是editemployee.aspx.cs。从该代码中,我调用了另一个项目,一个类库。我在那个类库中调用的方法看起来像......

        public static Employee GetItem(int employeeid)
        {
            try
            {
                Employee chosenemployee = EmployeeDB.GetItem(employeeid);
                chosenemployee.EmployeeInsuranceRecord = EmployeeInsuranceRecordManager.GetItem(employeeid);
                return chosenemployee;
            }
            catch (Exception ex)
            {
                if (ex is NullReferenceException)
                {
                    //How can I return gracefully from here
                    //without disrupting the user experience?
                }
                else
                {
                    throw ex;  //if it makes it this far, it must be some other unknown error and I need an exception to be thrown for real so I can track down the bug.
                }
            }
        }

基本上,此代码根据传递的 EmployeeID 从数据访问层获取完整的员工记录。如果异常是 NullReferenceException,则意味着伪造的 EmployeeID 不知何故通过了。在这种情况下,我希望返回到调用 .aspx.cs 页面,在此处停止整理 Employee 的过程,并显示一个 JavaScript 警报框,上面写着“提供的 EmployeeID 无效”。

所以我试着说:

            if (ex is NullReferenceException)
            {
                Response.Write("<script>alert('"The EmployeeID supplied is not valid."')</script>"); 
            }

但这在单独的类库中不起作用,它无法识别 Response.Write。

基本上我只需要一种方法来发出信号,通过这个方法,调用页面只是停止并优雅地显示错误,而不是给用户一个巨大的难看的不可恢复的错误消息。有什么建议吗?

【问题讨论】:

  • 永远不要使用throw ex 重新引发异常,而只需使用throw。在第一种情况下,您将丢失堆栈跟踪。有关详细信息,请参阅此question
  • 你们都很棒。这将真正帮助我解决这个特定问题,并了解更多关于一般错误处理的知识:)

标签: c# asp.net exception error-handling


【解决方案1】:

为什么不从 editemployee.aspx.cs 中获取您的 NullReferenceException? 比如:

try
{
    var employee = Employee.GetItem(int employeeid)
}
catch(NullReferenceException ex)
{
    Response.Write("<script>alert('"The EmployeeID supplied is not valid."')</script>"); 
}

另外,您应该使用is 运算符来过滤异常类型,而是在catch 语句中添加正确的类型。

catch 块可以指定要捕获的异常类型。这种类型称为异常过滤器,必须是 Exception 类型,或者派生自这种类型。应用程序定义的异常应派生自 ApplicationException。

(source)

最后,推荐的做法是抛出更多指定的Exception。在您的情况下,自定义 EmployeeNotFoundException 会更好地从您的业务层抛出。

catch(NullReferenceException ex)
{
     throw new EmployeeNotFoundException(ex);
}

【讨论】:

  • 发布后不久,我有一种感觉,这可能是我应该做的。这只是证实了这一点。谢谢!
  • ... 你不应该在 ASP.NET 中使用 Response.Write。您生成了无效的 HTML(内容在页面开头呈现)。
【解决方案2】:

如果你想使用你试过的代码你可以写HttpContext.Current.Response.Write("Whatever")

更好的解决方案是显示自定义错误页面。 这是一篇描述如何做到这一点的文章: http://www.asp.net/web-forms/tutorials/deployment/displaying-a-custom-error-page-cs

【讨论】:

  • 感谢您的链接,一定会查看的。
【解决方案3】:

有很多方法可以做到这一点,但也许只是返回一个空的 Employee 对象(或用一些标记代码填充它),然后在返回端检查你的标记代码,然后执行你的 JS 来提醒用户。

类似:

catch (Exception ex)
            {
                if (ex is NullReferenceException)
                {
                    return new Employee { Name = string.Empty }; // no idea what the Emp object looks like...
                    // or
                    return new Employee { Name = "666" };
                }
                    else
                    {
                        throw ex;  //if it makes it this far, it must be some other unknown error and I need an exception to be thrown for real so I can track down the bug.
                    }
                }

不是很好,但可行。

【讨论】:

  • 检查这样的异常类型真的很难看。你永远不应该这样做!只需抓住 NullReferenceException
  • 同意,但如前所述,它符合他的要求。 OP 暗示,至少对于这种特定类型的异常,他希望能够将此类信息返回到他的表示层,在这种情况下是使用 Javascript。从技术上讲,他正在捕获 NullReferenceException(尽管他应该在更高一级执行此操作,而不是在通用异常中)。
【解决方案4】:
  1. 首先你获取 Employee 的方法 (EmployeeDB.GetItem(employeeid); ) 应该返回 null 而不是抛出异常。在对对象进行任何操作之前,您应该进行一次空检查。

  2. 其次,我们不应该抛出 ex,除非您要添加其他信息。而只是说“扔”,因为这不会吃掉你的堆栈跟踪。另外,如果你没有在你的异常块中做任何事情,就让异常冒泡并在那里处理。

在您的情况下,如果您检查 null,则不需要处理异常。

【讨论】:

  • 很高兴知道只使用“throw”代替。谢谢。
【解决方案5】:

显示方式不对,应该是这样的:

HttpContext.Current.Response.Write("alert('"提供的 EmployeeID 无效。"')");

【讨论】:

    【解决方案6】:

    我认为在代码中使用 Response.Write 不是一个好主意,因为它将在页面的开头呈现(甚至在 HTML 标记之前)。但是有几种选择:

    1. 您可以在代码隐藏页面中捕获 NullReferenceException。在那里您可以访问该页面并可以调用 ClientScript.RegisterScript 或类似名称。

    2. 从库中的代码中,您可以使用 HttpContext.Current.Response 访问 Response 对象。

    你应该像这样捕获异常

    catch (NullreferenceException ex)
    {
       // handle exception, e.g.
       HttpContext.Current.Response.Write("...");
    }  
    

    所有其他异常都将在堆栈中向上遍历。

    编辑: 您可以选择以下选项,而不是直接写入响应(这不是一个好主意):

    1. 使用 HttpContext.Current.Response.Redirect("Error.aspx"); 重定向到另一个页面(解释错误);
    2. 注册 JavaScript

      catch (NullreferenceException ex)
      {
          string javaScript = "alert('The EmployeeID supplied is not valid');";
          HttpContext.Current.Page.ClientScript.RegisterStartupScript(typeof(thePage), "myScript", javaScript, true);
      }
      

    【讨论】:

      猜你喜欢
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多