4
catch(Exception ex)
{
    //do what you want here

    //When type of exception is System.Web.Services.Protocols.SoapException
    //if (ex.Code.Name.Equals("Client"))
    //{
    //      msg = "service's function not exist";
    //}
    //else if (ex.Code.Name.Equals("Server"))
    //{
    //     msg = "function error"
    //}
    //else
    //{
    //     msg = "unknown";
    //}
    //MessageBox.Show(msg, "error", MessageBoxButtons.OK);

**But ex is not System.Web.Services.Protocols.SoapException so I cannot call ex.Code.Name.Equals("Client")**


//When System.Net.WebException
//switch (ex.Status)
//{
//   case System.Net.WebExceptionStatus.ConnectFailure:
//              do some thing
                break;
//   case System.Net.WebExceptionStatus.Timeout:
                //do some thing
                break;
//    case System.Net.WebExceptionStatus.ProtocolError:
            switch (((System.Net.HttpWebResponse)ex.Response).StatusCode)
            {
                  case System.Net.HttpStatusCode.NotFound:
                        //do some thing
                        break;
                    case System.Net.HttpStatusCode.ServiceUnavailable:
                        //do some thing
                        break;
                    case System.Net.HttpStatusCode.Unauthorized:
                        //do some thing
                        break;
                    default:
                        //do some thing
                        break;
                }
                break;
            default:
                //do some thing
                break;
        }
}

但异常不是 System.Net.WebException。所以不能调用 ex.Status

我的问题:

我有一个 Smartclient 软件,包括作为客户端的 WindowsForm 和作为服务器的 Web 服务。客户端和服务器都是 n 层应用程序,我已经测试过,发现从客户端调用服务时有任何问题

  1. 在 app.config: 服务路径错误。我抓住System.NotSupportedException
  2. 或者当服务器无法连接时:System.Net.WebExceptionStatus
  3. 服务器的 webconfig 错误:System.InvalidOperationException
  4. 服务抛出异常:System.Web.Services.Protocols.SoapException ...

我的点子

我称作为所有其他异常类型的代表的异常是代表 AlException 我有命名空间:Common 和两个类代表AlException.cs和BusinessExceptionHandler.cs

使用参数作为 (representativeAlException ex) 创建一个通用函数

            try
            {
                Err_LogCheck.Service1.Service1 service = new Err_LogCheck.Service1.Service1();
                return service.getDeviceByZero(ZERO);
            }
            catch (Common.representativeAlException ex)
            {
                Common.BusinessExceptionHandler.ProcessException(ex);
            }

我想做的事

调用服务的位置。只有一个 catch 块可以处理所有类型的异常

ProcessException(representativeAlException ex)函数中

switch (ex)
{
case System.InvalidOperationException:
 //Do some thing
 break;
case System.NotSupportedException:
 //Do some thing
 break;
case System.Web.Services.Protocols.SoapException:
 //do some thing
 break;
...
...
4

4 回答 4

16

要处理所有异常,请使用 Exception 类。

try
{

}
catch(Exception ex)
{
     switch (ex.GetType().ToString())
     {
         case "System.InvalidOperationException":
              //cast ex to specific type of exception to use it's properties
              ((InvalidOperationException)ex).SomeMethod();
         break;
         case "System.NotSupportedException":
             ((System.NotSupportedException)ex).AnotherMethod();
         break;
         case "System.Web.Services.Protocols.SoapException":
             ((System.Web.Services.Protocols.SoapException)ex).OtherMethod();
         break;
     }

}

为什么你不能只使用多个 catch 块呢?

于 2012-10-04T01:06:07.403 回答
5

User2808350是正确的,try catch 块可以有许多不同的 catch 是有原因的,但是有时你会发现在使用这种模式时你在重复自己 (DRY)。

可以产生简洁易读的代码的另一种方法是使用is运算符,如果您的异常是特定类型的实例或派生自该类型的实例,则该运算符的计算结果为 true。不幸的是,不能在 switch 块中使用is运算符,因此您必须使用 if-then-else。

这是我测试异常类型并相应设置退出代码的示例。

try
{
    // try something
}
catch (Exception e)
{
    if (e is FileNotFoundException)
        Environment.ExitCode = 2;
    else if (e is InvalidOperationException)
        Environment.ExitCode = 1;
    else
        Environment.ExitCode = 42;
    throw;
}
于 2015-10-23T11:39:12.740 回答
4

现在这是一项语言功能。只需使用 switch/case 语句

提问者的第一次尝试,在问题的代码片段中被注释掉,现在是最简单也是我认为最好的方法。

实际上,我在试图弄清楚 Resharper 对其建议的改进之一做了什么时遇到了这个问题。我仍然不能 100% 确定所涉及的术语,因为我能找到的唯一文档是解释Discards,并且只在传递“与 is 和 switch 关键字匹配的模式”时提到,这也在执行。

正如 Onkel-j 建议的那样,我已经开始使用“if ex is Type”链:

try
{
    doWork();
}
catch (Exception ex)
{
    if (ex is SpecificExceptionType)
    {
        //todo
    }
    else 
    {
        //etc
    }
}

但 resharper 建议我让它将其更改为开关/案例:

try
{
    doWork();
}
catch (Exception ex)
{
    switch (ex)
    {
        case SpecificExceptionType _:
            //todo
            break;            
        default:
            //etc
            break;
    }
}

Resharper 已经使用Discards进行了一种自动处理 并丢弃了未使用的变量。如果您需要实际使用异常作为特定类型,请为其命名以代替下划线:

try
{
    doWork();
}
catch (Exception ex)
{
    switch (ex)
    {
        case SpecificExceptionType specific:
            HandleSpecificException(specific);
            break;            
        default:
            //etc
            break;
    }
}

或者回答原来的问题:

catch(Exception ex)
{
    //do what you want here
    
    switch(ex)
    {
        case System.Web.Services.Protocols.SoapException soapEx:        
            if (soapEx.Code.Name.Equals("Client"))
            {
                  msg = "service's function not exist";
            }
            else if (soapEx.Code.Name.Equals("Server"))
            {
                 msg = "function error"
            }
            else
            {
                 msg = "unknown";
            }
            MessageBox.Show(msg, "error", MessageBoxButtons.OK);    
            break;
        case System.Net.WebException webEx:
            switch (webEx.Status)
            {
               case System.Net.WebExceptionStatus.ConnectFailure:
                    //do some thing
                    break;
               case System.Net.WebExceptionStatus.Timeout:
                    //do some thing
                    break;
                case System.Net.WebExceptionStatus.ProtocolError:
                    switch (((System.Net.HttpWebResponse)webEx.Response).StatusCode)
                    {
                        case System.Net.HttpStatusCode.NotFound:
                            //do some thing
                            break;
                        case System.Net.HttpStatusCode.ServiceUnavailable:
                            //do some thing
                            break;
                        case System.Net.HttpStatusCode.Unauthorized:
                            //do some thing
                            break;
                        default:
                            //do some thing
                            break;
                    }
                    break;
                default:
                    //do some thing
                    break;
            }
            break;
        default:
            //etc
            break;
    }
}
于 2020-03-20T12:00:05.247 回答
1

应该使用

try {

    ....

}
catch (System.Net.HttpStatusCode.NotFound)
{
 //do some thing
}    
catch (System.Net.HttpStatusCode.ServiceUnavailable)
{
 //do some thing
}

catch (System.Net.HttpStatusCode.Unauthorized)
{
 //do some thing
}

catch (System.Net.HttpStatusCode.NotFound)
{
 //do some thing
}    
catch (Exception)
{
 //do some thing
}

最好使用 swicth

于 2013-09-23T18:30:02.307 回答