C# 如何捕获异常并检查它是否包含字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/294622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 22:00:32  来源:igfitidea点击:

C# How do I catch an exception and check if it contains a string?

c#exception

提问by

I'm getting an exception which says "Access Denied" when the users permissions are sufficient, how do I catch an exception and check for "Access Denied" so that I can show the user a friendlier "Sorry Access Denied" message?

当用户权限足够时,我收到一个显示“拒绝访问”的异常,如何捕获异常并检查“拒绝访问”,以便我可以向用户显示更友好的“拒绝访问”消息?

Thanks Beginner :-)

谢谢初学者:-)

回答by Ed S.

If you are using a try catch block...

如果您使用的是 try catch 块...

try
{
    //error occurs
}
catch (Exception ex)
{
    MessageBox.show(ex.Message);
}

Obviously that is pretty crappy error handling, but it shows that the Exception object contains the error string. You can narrow down the handling of different exceptions by catching different exception types.

显然,这是非常糟糕的错误处理,但它表明 Exception 对象包含错误字符串。您可以通过捕获不同的异常类型来缩小不同异常的处理范围。

Try
{
    //error occurs
}
catch (AccessDeniedException ex)
{
    MessageBox.show(ex.Message);
}
catch (FieldAccessException)
{

}
// etc...

回答by Ed Marty

You don't really want to check the string of the message, you want to check the type of the message, which can be easily done by catching only the type(s) of exception you are checking for. The following example will catch two different types of exceptions and do different actions based on what if any error occurs. (Note: the names of the exceptions are made up)

您并不是真的想要检查消息的字符串,而是想要检查消息的类型,这可以通过仅捕获您正在检查的异常类型来轻松完成。下面的示例将捕获两种不同类型的异常,并根据发生任何错误时的情况执行不同的操作。(注:例外的名称是编造的)

try {
    ...
} catch (SomeKindOfException ex) {
    MessageBox.Show(ex.Message);
} catch (AccessDeniedException ex) {
    //Do something else
}

回答by Tamas Czinege

Simple:

简单的:

try
{
    YourCommandWhichResultsInDeniedAccess();
}
catch (AccessDeniedException)
{
    MessageBox.Show('Access Denied');
}

If you don't know the type of the Exception and/or you want to check the Exception message instead, do the following:

如果您不知道异常的类型和/或您想改为检查异常消息,请执行以下操作:

try
{
    YourCommandWhichResultsInDeniedAccess();
}
catch (Exception e)
{
   if (e.Message == 'Access Denied')
   {
       MessageBox.Show('Access Denied')
   }
}

回答by Brian H. Madsen

First off - should look into the permissions issue rather than tackling the exception solely. If "Access Denied" is thrown then there must either be a permissions issues or a lock of some sort.

首先 - 应该调查权限问题,而不是单独处理异常。如果抛出“拒绝访问”,则必须存在权限问题或某种锁定。

Anyways, "Message" is a string and you can use the .Contains method on it to check for "Access Denied".

无论如何,“消息”是一个字符串,您可以使用 .Contains 方法来检查“拒绝访问”。

You can't change the "Message" property as it has no setter, but you can handle the exception and display a polite message.

您无法更改“消息”属性,因为它没有设置器,但您可以处理异常并显示礼貌消息。

MessageBox.Show("Sorry, Access Denied"); for instance.

MessageBox.Show("抱歉,拒绝访问"); 例如。

Edit: as mentioned above you should check for the type of exception. e.g. AccessDeniedException rather than use something as generic as "Exception".

编辑:如上所述,您应该检查异常类型。例如 AccessDeniedException 而不是使用像“异常”这样的通用内容。



try
        {
            // code here which throws exception
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains("Access Denied"))
            {
                MessageBox.Show("Sorry, Access Denied", "This is a polite error message");
            }
        }

回答by Jeff Atwood

I think the safest thing to do here (and surprisingly none of the answers show this) is to

我认为在这里做的最安全的事情(令人惊讶的是没有一个答案显示这一点)是

  • Catch as specifican exception type as you can. Really try to avoid catching all exceptions.
  • Test the exception message for string.ToLowerInvariant()containing your target string.
  • re-throwif it's not what you expect!
  • 尽可能捕获特定的异常类型。真的尽量避免捕获所有异常。
  • 测试string.ToLowerInvariant()包含目标字符串的异常消息。
  • 重新 -throw如果它不是你所期望的!

like so:

像这样:

try
{
    int result = DoStuff(param);
}
catch (System.IO.IOException ioex)
{
    if (ioex.Message.ToLowerInvariant().Contains("find me"))
    {
        .. do whatever ..
    }
    else
    {
        // no idea what just happened; we gotta crash
        throw;
    }
}

回答by Arun Prasad E S

Just a modification from above, but working with datatable and database and dropdownlist

只是从上面的修改,但使用数据表和数据库和下拉列表

try {
        drop_grup_head.SelectedValue = ds.Rows[0]["group_head"].ToString();
     }
     catch (Exception exce ) {
        if (exce.Message.ToLowerInvariant().Contains("does not exist in the list")) {
           drop_grup_head.SelectedValue = "0";
        }
     }

回答by Tomas Kubes

Using exception filters in C# 6.0it is even easier:

在 C# 6.0 中使用异常过滤器更容易:

try
{
    int result = DoStuff(param);
}
catch (IOException ex) 
when (ex.Message.ToLowerInvariant().Contains("find me")) 
{
    //.. do whatever ..
}

Old style C# solution would be

旧式 C# 解决方案是

try
{
    int result = DoStuff(param);
}
catch (System.IO.IOException ex)
{
    if (ex.Message.ToLowerInvariant().Contains("find me"))
    {
        //.. do whatever ..
    }
    else
    {
        throw;
    }
}

In case of both variants you will get the same Stack Trace. In the first variant exception is not caught at all in the second variant exception is retrowned. But there is one important difference:

在这两种变体的情况下,您将获得相同的堆栈跟踪。在第一个变体中,异常根本没有被捕获,而在第二个变体中,异常被重新抛出。但是有一个重要的区别:

In the case of exception filter:

在异常过滤器的情况下:

  • Stack trace is preserved.
  • Stack is preserved.
  • 堆栈跟踪被保留。
  • 堆栈被保留。

In case of catch-if-throw:

在 catch-if-throw 的情况下:

  • Stack trace is preserved.
  • Stack is NOT preserved.
  • 堆栈跟踪被保留。
  • 堆栈不保留

What is the difference between stack and stacktrace?

堆栈和堆栈跟踪有什么区别?

Stacktrace is a snapshot of the stack.

Stacktrace 是堆栈的快照。

Practically the only difference you could see in these variants is that you can have different memory dump (if you combine C# and C++).

实际上,您可以在这些变体中看到的唯一区别是您可以拥有不同的内存转储(如果您将 C# 和 C++ 结合使用)。

Localization

本土化

In case you are catching some third party exception which is localized into several languages and you cannot check exceptions by type or code, beware that the message can be localized. There is a workaround for this. You can find an English message of exception. Catch the exception, start a new Thread with English culture and read the message property on the Thread with English culture and go back to your current thread with the result.

如果您正在捕获一些本地化为多种语言的第三方异常,并且您无法按类型或代码检查异常,请注意消息可以本地化。有一个解决方法。您可以找到异常的英文消息。捕获异常,启动一个新的英文主题线程并阅读具有英文文化的线程上的消息属性,然后返回到当前线程的结果。

Conclusion

结论

You should use exception filter, it is not only syntactic sugar, but you will have also correct memory dumps.

您应该使用异常过滤器,它不仅是语法糖,而且您还将拥有正确的内存转储。

回答by Hesham Yassin

You can use the conditional catch feature:

您可以使用条件捕获功能:

try
{
    // code here which throws exception
}
catch (Exception ex) when(ex.Message.Contains("Access Denied"))
{
    MessageBox.Show("Sorry, Access Denied", "This is a polite error message");
}