C# 英文的异常信息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/209133/
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
Exception messages in English?
提问by Carra
We are logging any exceptions that happen in our system by writing the Exception.Message to a file. However, they are written in the culture of the client. And Turkish errors don't mean a lot to me.
我们通过将 Exception.Message 写入文件来记录系统中发生的任何异常。但是,它们是根据客户的文化编写的。土耳其语的错误对我来说意义不大。
So how can we log any error messages in English without changing the users culture?
那么我们如何在不改变用户文化的情况下用英语记录任何错误消息呢?
采纳答案by mdb
This issue can be partially worked around. The Framework exception code loads the error messages from its resources, based on the current thread locale. In the case of some exceptions, this happens at the time the Message property is accessed.
这个问题可以部分解决。框架异常代码根据当前线程区域设置从其资源加载错误消息。在某些异常的情况下,这会在访问 Message 属性时发生。
For those exceptions, you can obtain the full US English version of the message by briefly switching the thread locale to en-US while logging it (saving the original user locale beforehand and restoring it immediately afterwards).
对于这些例外情况,您可以通过在记录时将线程区域设置切换为 en-US(事先保存原始用户区域设置并在之后立即恢复)来获取消息的完整美国英语版本。
Doing this on a separate thread is even better: this ensures there won't be any side effects. For example:
在单独的线程上执行此操作甚至更好:这确保不会有任何副作用。例如:
try
{
System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString()); //Will display localized message
ExceptionLogger el = new ExceptionLogger(ex);
System.Threading.Thread t = new System.Threading.Thread(el.DoLog);
t.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
t.Start();
}
Where the ExceptionLogger class looks something like:
ExceptionLogger 类如下所示:
class ExceptionLogger
{
Exception _ex;
public ExceptionLogger(Exception ex)
{
_ex = ex;
}
public void DoLog()
{
Console.WriteLine(_ex.ToString()); //Will display en-US message
}
}
However, as Joecorrectly points out in a comment on an earlier revision of this reply, some messages are already (partially) loaded from the language resources at the time the exception is thrown.
但是,正如Joe在对该回复的早期修订版的评论中正确指出的那样,在抛出异常时,某些消息已经(部分)从语言资源加载。
This applies to the 'parameter cannot be null' part of the message generated when an ArgumentNullException("foo") exception is thrown, for example. In those cases, the message will still appear (partially) localized, even when using the above code.
例如,这适用于抛出 ArgumentNullException("foo") 异常时生成的消息的“参数不能为空”部分。在这些情况下,即使使用上述代码,消息仍会(部分)本地化。
Other than by using impractical hacks, such as running all your non-UI code on a thread with en-US locale to begin with, there doesn't seem to be much you can do about that: the .NET Framework exception code has no facilities for overriding the error message locale.
除了使用不切实际的技巧,例如在一个带有 en-US 语言环境的线程上运行所有非 UI 代码之外,您似乎无能为力:.NET Framework 异常代码没有用于覆盖错误消息区域设置的工具。
回答by morechilli
I would imagine one of these approaches:
我会想象这些方法之一:
The exceptions are only ever read by you, i.e. they are not a client feature, so you can use hardwired non localised strings that won't change when you run in Turkish mode.
Include an error code e.g.
0x00000001
with each error so that you can easily look it in up in an English table.
异常只能由您读取,即它们不是客户端功能,因此您可以使用在土耳其语模式下运行时不会更改的硬连线非本地化字符串。
包括错误代码,例如
0x00000001
每个错误,以便您可以轻松地在英文表中查找。
回答by mdb
CultureInfo oldCI = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture ("en-US");
Thread.CurrentThread.CurrentUICulture=new CultureInfo("en-US");
try
{
System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString())
}
Thread.CurrentThread.CurrentCulture = oldCI;
Thread.CurrentThread.CurrentUICulture = oldCI;
Without WORKAROUNDS.
没有变通办法。
Tks :)
tks :)
回答by Branko Dimitrijevic
You should log the call stack instead of just error message (IIRC, simple exception.ToString() should do that for you). From there, you can determine exactly where the exception originated from, and usually deduce which exception it is.
您应该记录调用堆栈,而不仅仅是错误消息(IIRC,简单的 exception.ToString() 应该为您做到这一点)。从那里,您可以确定异常的确切来源,并通常推断出它是哪个异常。
回答by user461128
You can search for the original exception message at unlocalize.com
您可以在unlocalize.com 上搜索原始异常消息
回答by danobrega
Windows needs to have the UI language you want to use installed. It it doesn't, it has no way of magically knowing what the translated message is.
Windows 需要安装您要使用的 UI 语言。它没有,它无法神奇地知道翻译的消息是什么。
In an en-US windows 7 ultimate, with pt-PT installed, the following code:
在安装了 pt-PT 的 en-US windows 7 Ultimate 中,以下代码:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("pt-PT");
string msg1 = new DirectoryNotFoundException().Message;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
string msg2 = new FileNotFoundException().Message;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
string msg3 = new FileNotFoundException().Message;
Produces messages in pt-PT, en-US and en-US. Since there is no French culture files installed, it defaults to the windows default (installed?) language.
以 pt-PT、en-US 和 en-US 生成消息。由于没有安装法语文化文件,它默认为 windows 默认(已安装?)语言。
回答by Barbarian
I know this is an old topic, but I think my solution may be quite relevant to anyone who stumbles across it in a web search:
我知道这是一个古老的话题,但我认为我的解决方案可能与在网络搜索中偶然发现它的任何人都非常相关:
In the exception logger you could log ex.GetType.ToString, which would save the name of the exception class. I would expect that the name of a class ought to be independent of language and would therefore always be represented in English (e.g. "System.FileNotFoundException"), though at present I don't have access to a foreign language system to test out the idea.
在异常记录器中,您可以记录 ex.GetType.ToString,这将保存异常类的名称。我希望类的名称应该独立于语言,因此总是用英语表示(例如“System.FileNotFoundException”),尽管目前我无法访问外语系统来测试主意。
If you really want the error message text as well you could create a dictionary of all possible exception class names and their equivalent messages in whatever language you prefer, but for English I think the class name is perfectly adequate.
如果你真的想要错误消息文本,你可以用你喜欢的任何语言创建一个所有可能的异常类名称及其等效消息的字典,但对于英语,我认为类名称是完全足够的。
回答by Vortex852456
Setting Thread.CurrentThread.CurrentUICulture
will be used to localize the exceptions. If you need two kinds of exceptions (one for the user, one for you) you can use the following function to translate the exception-message. It's searching in the .NET-Libraries resources for the original text to get the resource-key and then return the translated value. But there's one weakness I didn't find a good solution yet: Messages, that contains {0} in resources will not be found. If anyone has a good solution I would be grateful.
设置Thread.CurrentThread.CurrentUICulture
将用于本地化异常。如果您需要两种异常(一种为用户,一种为您),您可以使用以下函数来翻译异常消息。它在 .NET-Libraries 资源中搜索原始文本以获取资源键,然后返回翻译后的值。但是有一个我还没有找到好的解决方案的弱点:将找不到资源中包含 {0} 的消息。如果有人有好的解决方案,我将不胜感激。
public static string TranslateExceptionMessage(Exception ex, CultureInfo targetCulture)
{
try
{
Assembly assembly = ex.GetType().Assembly;
ResourceManager resourceManager = new ResourceManager(assembly.GetName().Name, assembly);
ResourceSet originalResources = resourceManager.GetResourceSet(Thread.CurrentThread.CurrentUICulture, createIfNotExists: true, tryParents: true);
ResourceSet targetResources = resourceManager.GetResourceSet(targetCulture, createIfNotExists: true, tryParents: true);
foreach (DictionaryEntry originalResource in originalResources)
if (originalResource.Value.ToString().Equals(ex.Message.ToString(), StringComparison.Ordinal))
return targetResources.GetString(originalResource.Key.ToString(), ignoreCase: false); // success
}
catch { }
return ex.Message; // failed (error or cause it's not smart enough to find texts with '{0}'-patterns)
}
回答by MPelletier
A contentious point perhaps, but instead of setting the culture to en-US
, you can set it to Invariant
. In the Invariant
culture, the error messages are in English.
也许有争议的一点,但不是将文化设置为en-US
,您可以将其设置为Invariant
。在Invariant
文化中,错误消息是英文的。
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
It has the advantage of not looking biased, especially for non-American English speaking locales. (a.k.a. avoids snide remarks from colleagues)
它的优点是看起来不会有偏见,特别是对于非美国英语语言环境。(又名避免来自同事的讽刺评论)
回答by user3472484
Override exception message in catch block using extension method, Check thrown message is from code or not as mentioned below.
使用扩展方法覆盖 catch 块中的异常消息,检查抛出的消息是否来自代码,如下所述。
public static string GetEnglishMessageAndStackTrace(this Exception ex)
{
CultureInfo currentCulture = Thread.CurrentThread.CurrentUICulture;
try
{
dynamic exceptionInstanceLocal = System.Activator.CreateInstance(ex.GetType());
string str;
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
if (ex.Message == exceptionInstanceLocal.Message)
{
dynamic exceptionInstanceENG = System.Activator.CreateInstance(ex.GetType());
str = exceptionInstanceENG.ToString() + ex.StackTrace;
}
else
{
str = ex.ToString();
}
Thread.CurrentThread.CurrentUICulture = currentCulture;
return str;
}
catch (Exception)
{
Thread.CurrentThread.CurrentUICulture = currentCulture;
return ex.ToString();
}