从另一个类的catch中优雅地返回.aspx.cs文件

时间:2011-12-13 07:42:06

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

我有一个名为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。

基本上我只需要一种方法来通知这个方法,调用页面只是停止并优雅地显示错误,而不是给用户一个巨大的丑陋的不可恢复的错误消息。有什么提示吗?

6 个答案:

答案 0 :(得分:1)

如果您想使用您尝试的代码,可以编写HttpContext.Current.Response.Write("Whatever")

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

答案 1 :(得分:1)

有很多方法可以做到这一点,但也许只返回一个空的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.
                    }
                }

不太好,但可行。

答案 2 :(得分:1)

  1. 首先获取Employee的方法(EmployeeDB.GetItem(employeeid); )应返回null而不是抛出异常。在对对象执行任何操作之前,您应该进行空检查。

  2. 其次,除非您要添加其他信息,否则我们不应该抛出ex。而只是说&#34; throw&#34;因为这不会吃掉你的堆栈痕迹。此外,如果你没有在你的异常块中做任何事情,只需让异常冒泡并在那里处理。

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

答案 3 :(得分: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);
}

答案 4 :(得分:1)

显示方法错误,应该是:

HttpContext.Current.Response.Write(&#34; alert(&#39;&#34;提供的EmployeeID无效。&#34;&#39;)&#34;);

答案 5 :(得分:1)

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

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

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

  3. 你应该像这样抓住

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

    所有其他例外情况都是未处理的,然后再向上走。

    编辑: 您没有直接写入Response(这不是一个好主意),而是有以下选项:

    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);
      }