如何处理多层ASP.NET Web应用程序中的异常

时间:2012-06-04 16:06:09

标签: asp.net exception-handling multi-layer

我有一个ASP.NET Web窗体应用程序,其中包含 UI 服务层存储库层

我的服务层中的一些方法与Web服务通信,因此我想在Try-Catch-Finally构造中包含对Web方法的所有调用。

假设我的服务层

中有以下方法
public RegistrationDetails GetRegistrationDetails(int userId)

public bool RegisterUser(UserData myUserData)

RegistrationDetailsmyUserData是对象类型(类)。

我关注的是:如果我在上面列出的方法的实现中创建了一个Try-Catch-Finally来包装对Web服务的调用,如果有异常,我该如何返回消息字符串返回类型为RegistrationDetailsbool

我正在考虑为每个返回对象添加一个属性,但我不知道这是否是一个很好的解决方案。例如,而不是使用bool

public class RegisterResponse
{
   public bool isRegistered { get; set; }
   public string ExceptionMessage { get; set; }
}

public RegisterResponse RegisterUser(UserData myUserData)

然后检查ExceptionMessage是null还是String.Empty。这是一个好方法吗?感谢

2 个答案:

答案 0 :(得分:0)

1)正如IrishChieftain所提到的,将异常冒泡到表格中是好的,你将能够更好地回应异常

2)您还可以将引用参数作为数组来存储从方法

生成的异常消息
public bool RegisterUser(UserData myUserData, optional ref ArrayList<string> errors)
{
  if(error)
    errors.Add("This error occured")
}

3)对于Instance Object,你可以有一个ArrayList的Instance变量用于出错,并在属性中返回

public class MyClass
{
   private ArrayList<string> errors = new ArrayList<string>

   public ArrayList<string> ExceptionMessages()
   {
      get 
      {
          return errors;
      }
   }

  public RegistrationDetails GetRegistrationDetails(int userId) { }
}

//Used like this:
MyClass c = new MyClass();
c.GetRegistrationDetails();

if(c.ExceptionMessages > 0)
{
    //output errors
}

但我更喜欢第一种方法 - 出于输出格式化等灵活性

答案 1 :(得分:0)

将原始异常从服务传递到客户端(Web表单层)可能存在风险。如果它是数据库异常,则可能会公开数据库的详细信息。恶意用户可能会从自己的应用程序中调用您的服务层方法。

您可以在客户端级别上遇到两种类型的异常:

  1. 通信异常(连接到服务的问题)
  2. 服务器端错误(数据库问题,用户名不唯一,密码无效......其他业务规则例外)
  3. 第一种类型应该在您的Web表单层中的try-catch-finally中捕获,但是第二种类型应该在服务层中捕获,记录,然后包装在RegisterResponse对象中,如您所建议的那样。但是,您可以考虑使用一个预期错误的枚举(而不是使用ServerError成员来覆盖其他任何内容),而不是发送Exception.Message。您还可以向响应和日志条目添加EventId,以便您可以调查错误。

    public enum RegisterResponseError { NoError = 0, SystemError = 1, 
        UserNameNotUnique, PasswordInvalid, etc.  }
    
    public class RegisterResponse
    {
       public bool isRegistered { get; set; }
       public RegisterResponseError ErrorCode { get; set; }
    }
    

    然后在您的客户端代码中

    if(myRegisterResponse.ErrorCode == RegisterResponseError.NoError)
       // everything was fine
    else
      // show a suitable error message for ErrorCode and display EventId (if logging)
    

    您可以从服务中返回错误字符串,但最好是管理网络表单层中的任何内容,以防您需要本地化内容或稍后使用CMS。