영어로 된 예외 메시지?
예외를 작성하여 시스템에서 발생하는 모든 예외를 기록하고 있습니다.파일에 대한 메시지입니다.하지만, 그것들은 고객의 문화로 쓰여져 있습니다.터키식 오류는 저에게 큰 의미가 없습니다.
그렇다면 어떻게 하면 사용자 문화를 바꾸지 않고 영어로 오류 메시지를 기록할 수 있을까요?
이 문제는 부분적으로 해결할 수 있습니다.Framework 예외 코드는 현재 스레드 로케일을 기준으로 리소스에서 오류 메시지를 로드합니다.일부 예외의 경우 메시지 속성에 액세스할 때 이 문제가 발생합니다.
이러한 예외를 제외하고는 메시지를 기록하는 동안 스레드 로케일을 en-US로 잠시 전환하여 메시지의 전체 미국 영어 버전을 얻을 수 있습니다(원래 사용자 로케일을 사전에 저장한 후 즉시 복원).
별도의 스레드에서 이 작업을 수행하는 것이 훨씬 더 좋습니다. 이렇게 하면 부작용이 발생하지 않습니다.예:
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();
}
ExceptionLogger 클래스의 모양은 다음과 같습니다.
class ExceptionLogger
{
Exception _ex;
public ExceptionLogger(Exception ex)
{
_ex = ex;
}
public void DoLog()
{
Console.WriteLine(_ex.ToString()); //Will display en-US message
}
}
그러나 Joe가 이 응답의 이전 버전에 대한 주석에서 올바르게 지적했듯이 예외가 발생할 때 일부 메시지는 이미 (부분적으로) 언어 리소스에서 로드되었습니다.
이는 예를 들어 ArgumentNullException("foo") 예외가 발생할 때 생성되는 메시지의 '매개 변수 null일 수 없음' 부분에 적용됩니다.이러한 경우 메시지는 위의 코드를 사용하는 경우에도 부분적으로 현지화되어 표시됩니다.
처음부터 en-US 로케일이 있는 스레드에서 UI가 아닌 모든 코드를 실행하는 것과 같은 비실용적인 해킹을 사용하는 것 외에는, .NET Framework 예외 코드에는 오류 메시지 로케일을 재정의하는 기능이 없습니다.
의 여지가 있는 , 를 쟁의여가있점수일있도지만는대로 설정하는 에, 문를다같설이정는하과신음화논지▁a대▁perhaps▁to신는설정하▁content같이,▁the다▁instead음ious▁culture▁point문▁but▁of▁setting화.en-US
로 설정할 수 있습니다.Invariant
에서.에서Invariant
문화, 오류 메시지는 영어로 되어 있습니다.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
특히 미국인이 아닌 영어권 현지인들에게 편향적으로 보이지 않는 장점이 있습니다. (동료들의 비꼬는 발언을 피함)
코드로 변경할 수 없을 정도로 너무 일찍 로드된 예외 텍스트(예: mscorlib)에 대해서도 코딩이 필요 없고 작동하는 솔루션이 있습니다.
모든 경우에 항상 적용할 수 있는 것은 아니지만(메인 .exe 파일 외에 .config 파일을 생성할 수 있어야 하므로 설정에 따라 다름) 저에게 적합합니다.그래서, 그냥 만들어 보세요.app.config
( dev, (는또a))에서.[myapp].exe.config
또는web.config
예를 들어 다음과 같은 라인이 포함되어 있습니다.
<configuration>
...
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="mscorlib.resources" publicKeyToken="b77a5c561934e089"
culture="fr" /> <!-- change this to your language -->
<bindingRedirect oldVersion="1.0.0.0-999.0.0.0" newVersion="999.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.resources" publicKeyToken="b77a5c561934e089"
culture="fr" /> <!-- change this to your language -->
<bindingRedirect oldVersion="1.0.0.0-999.0.0.0" newVersion="999.0.0.0"/>
</dependentAssembly>
<!-- add other assemblies and other languages here -->
</assemblyBinding>
</runtime>
...
</configuration>
하는 것입니다.mscorlib
의 및 문서System.Xml
의 버전에 의 1 서로 999 사이전문된대의로에리어프스소됨스랑설정해는화에버의문로▁"▁'()▁is리,에됨스설소1정▁to▁set의s▁resources▁9▁"99된▁and▁betweenculture는화▁for▁in▁("fr
하지 않는 버전 ...가 존재하지 않는 어셈블리(임의 버전 999)입니다.
따라서 CLR이 이 두 어셈블리(mscorlib 및 System.xml)에 대한 프랑스어 리소스를 찾을 때 이를 찾지 못하고 영어로 정상적으로 돌아갑니다.컨텍스트 및 테스트에 따라 이러한 리디렉션에 다른 어셈블리(현지화된 리소스를 포함하는 어셈블리)를 추가할 수 있습니다.
물론 Microsoft에서 지원하지 않는다고 생각하기 때문에 사용자의 책임 하에 사용하십시오.문제가 발견된 경우 이 구성을 제거하고 관련이 없는지 확인하면 됩니다.
사용할 UI 언어가 설치되어 있어야 합니다.그렇지 않다면, 그것은 번역된 메시지가 무엇인지 마법처럼 알 수 있는 방법이 없습니다.
pt-PT가 설치된 en-US 윈도우즈 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;
PT-PT, en-US 및 en-US로 메시지를 생성합니다.프랑스어 문화 파일이 설치되어 있지 않기 때문에 기본적으로 Windows 기본(설치되어 있습니까?) 언어로 설정됩니다.
이것이 오래된 주제라는 것을 알지만, 저는 제 해결책이 웹 검색에서 그것을 우연히 발견한 사람들과 상당히 관련이 있을 것이라고 생각합니다.
예외 로거에서 ex를 기록할 수 있습니다.GetType.ToString. 예외 클래스의 이름을 저장합니다.클래스의 이름은 언어와 독립적이어야 하며 따라서 항상 영어로 표시되어야 합니다(예: "시스템")."FileNotFoundException"), 그러나 현재 저는 아이디어를 테스트할 수 있는 외국어 시스템에 액세스할 수 없습니다.
오류 메시지 텍스트를 정말 원한다면 가능한 모든 예외 클래스 이름과 해당하는 메시지를 원하는 언어로 사전을 만들 수 있지만 영어의 경우 클래스 이름이 완벽하게 적합하다고 생각합니다.
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;
해결 방법 없음.
Tks :)
정Thread.CurrentThread.CurrentUICulture
예외를 현지화하는 데 사용됩니다.두 가지 유형의 예외(사용자용 하나, 사용자용 하나)가 필요한 경우 다음 함수를 사용하여 예외 메시지를 변환할 수 있습니다.에서 검색하고 있습니다.NET - 원본 텍스트의 리소스를 라이브러리하여 리소스 키를 가져온 다음 변환된 값을 반환합니다.그러나 아직 좋은 솔루션을 찾지 못한 약점이 하나 있습니다. 리소스에 {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)
}
.NET 프레임워크는 두 부분으로 구성됩니다.
- .NET 프레임워크 자체
- .NET 프레임워크 언어 팩
모든 텍스트(예: 예외 메시지, MessageBox의 버튼 레이블 등)는 .NET 프레임워크 자체에서 영어로 제공됩니다.언어 팩에는 현지화된 텍스트가 있습니다.
사용자의 정확한 상황에 따라 언어 팩을 제거하는 것이 해결책이 될 수 있습니다(즉, 클라이언트에게 그렇게 하라고 함).이 경우 예외 텍스트는 영어로 작성됩니다.그러나 프레임워크에서 제공하는 다른 모든 텍스트도 영어입니다(예: MessageBox의 버튼 레이블, ApplicationCommands의 키보드 단축키).
Undercover 1989 응답을 기반으로 하지만 매개 변수와 메시지가 여러 리소스 문자열(예: 인수 예외)로 구성된 경우를 고려합니다.
public static string TranslateExceptionMessage(Exception exception, CultureInfo targetCulture)
{
Assembly a = exception.GetType().Assembly;
ResourceManager rm = new ResourceManager(a.GetName().Name, a);
ResourceSet rsOriginal = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, true, true);
ResourceSet rsTranslated = rm.GetResourceSet(targetCulture, true, true);
var result = exception.Message;
foreach (DictionaryEntry item in rsOriginal)
{
if (!(item.Value is string message))
continue;
string translated = rsTranslated.GetString(item.Key.ToString(), false);
if (!message.Contains("{"))
{
result = result.Replace(message, translated);
}
else
{
var pattern = $"{Regex.Escape(message)}";
pattern = Regex.Replace(pattern, @"\\{([0-9]+)\}", "(?<group$1>.*)");
var regex = new Regex(pattern);
var replacePattern = translated;
replacePattern = Regex.Replace(replacePattern, @"{([0-9]+)}", @"${group$1}");
replacePattern = replacePattern.Replace("\\$", "$");
result = regex.Replace(result, replacePattern);
}
}
return result;
}
저는 다음과 같은 접근법 중 하나를 상상할 것입니다.
예외는 항상 사용자만 읽습니다. 즉, 클라이언트 기능이 아니므로 터키어 모드에서 실행할 때 변경되지 않는 유선 비국소화 문자열을 사용할 수 있습니다.
오류 코드를 포함합니다.
0x00000001
영어 표에서 쉽게 찾을 수 있도록 각각의 오류와 함께.
저는 같은 상황을 겪었고, 여기와 다른 곳에서 찾은 모든 대답은 도움이 되지 않았거나 만족스럽지 않았습니다.
- 영어의 예외 적용 언어
- C# - 응용 프로그램이 다른 언어로 되어 있을 때 영어로 된 예외 메시지가 표시됩니까?
- 디버깅하는 동안 Visual Studio 예외 메시지 언어를 영어로 변경하는 방법
- 예외 메시지의 번역을 어떻게 처리합니까?
- 현지화된 .NET 예외 메시지를 완전히 피하는 방법
그Thread.CurrentUICulture
예외의 되지만 .net 예의언변경만에않변습다니지경되대는서해에 대해서는 .Win32Exception
윈도우즈 UI 자체의 언어로 윈도우즈 리소스를 사용합니다.그래서 나는 결코 메시지를 인쇄할 수 없었습니다.Win32Exception
독일어 대신 영어로, 심지어 사용하지도 않습니다.FormatMessage()
된 에같바이에 기술된 바와
영어로 Win32Exception을 얻는 방법은 무엇입니까?
따라서 여러 언어에 대한 기존 예외 메시지의 대부분을 외부 파일에 저장하는 자체 솔루션을 만들었습니다.원하는 언어로 정확한 메시지를 받을 수는 없지만 현재보다 훨씬 많은 해당 언어로 메시지를 받을 수 있습니다(이해할 수 없는 언어로 된 메시지).
언어가 Windows 할 수 있습니다.CreateMessages()
에 특화된 .
SaveMessagesToXML()
합니다.
LoadMessagesFromXML()
메시지가 된 모든 합니다. XML 파일 로드
언어가 다른 여러 Windows 설치 환경에서 XML 파일을 만들 때 필요한 모든 언어가 곧 제공됩니다.
여러 개의 MUI 언어 팩이 설치되어 있을 때 하나의 Windows에서 여러 언어에 대한 텍스트를 만들 수 있지만, 저는 아직 테스트하지 않았습니다.
VS2008을 통해 테스트를 거쳐 바로 사용할 수 있습니다.의견과 제안을 환영합니다!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Xml;
public struct CException
{
//----------------------------------------------------------------------------
public CException(Exception i_oException)
{
m_oException = i_oException;
m_oCultureInfo = null;
m_sMessage = null;
}
//----------------------------------------------------------------------------
public CException(Exception i_oException, string i_sCulture)
{
m_oException = i_oException;
try
{ m_oCultureInfo = new CultureInfo(i_sCulture); }
catch
{ m_oCultureInfo = CultureInfo.InvariantCulture; }
m_sMessage = null;
}
//----------------------------------------------------------------------------
public CException(Exception i_oException, CultureInfo i_oCultureInfo)
{
m_oException = i_oException;
m_oCultureInfo = i_oCultureInfo == null ? CultureInfo.InvariantCulture : i_oCultureInfo;
m_sMessage = null;
}
//----------------------------------------------------------------------------
// GetMessage
//----------------------------------------------------------------------------
public string GetMessage() { return GetMessage(m_oException, m_oCultureInfo); }
public string GetMessage(String i_sCulture) { return GetMessage(m_oException, i_sCulture); }
public string GetMessage(CultureInfo i_oCultureInfo) { return GetMessage(m_oException, i_oCultureInfo); }
public static string GetMessage(Exception i_oException) { return GetMessage(i_oException, CultureInfo.InvariantCulture); }
public static string GetMessage(Exception i_oException, string i_sCulture)
{
CultureInfo oCultureInfo = null;
try
{ oCultureInfo = new CultureInfo(i_sCulture); }
catch
{ oCultureInfo = CultureInfo.InvariantCulture; }
return GetMessage(i_oException, oCultureInfo);
}
public static string GetMessage(Exception i_oException, CultureInfo i_oCultureInfo)
{
if (i_oException == null) return null;
if (i_oCultureInfo == null) i_oCultureInfo = CultureInfo.InvariantCulture;
if (ms_dictCultureExceptionMessages == null) return null;
if (!ms_dictCultureExceptionMessages.ContainsKey(i_oCultureInfo))
return CreateMessage(i_oException, i_oCultureInfo);
Dictionary<string, string> dictExceptionMessage = ms_dictCultureExceptionMessages[i_oCultureInfo];
string sExceptionName = i_oException.GetType().FullName;
sExceptionName = MakeXMLCompliant(sExceptionName);
Win32Exception oWin32Exception = (Win32Exception)i_oException;
if (oWin32Exception != null)
sExceptionName += "_" + oWin32Exception.NativeErrorCode;
if (dictExceptionMessage.ContainsKey(sExceptionName))
return dictExceptionMessage[sExceptionName];
else
return CreateMessage(i_oException, i_oCultureInfo);
}
//----------------------------------------------------------------------------
// CreateMessages
//----------------------------------------------------------------------------
public static void CreateMessages(CultureInfo i_oCultureInfo)
{
Thread oTH = new Thread(new ThreadStart(CreateMessagesInThread));
if (i_oCultureInfo != null)
{
oTH.CurrentCulture = i_oCultureInfo;
oTH.CurrentUICulture = i_oCultureInfo;
}
oTH.Start();
while (oTH.IsAlive)
{ Thread.Sleep(10); }
}
//----------------------------------------------------------------------------
// LoadMessagesFromXML
//----------------------------------------------------------------------------
public static void LoadMessagesFromXML(string i_sPath, string i_sBaseFilename)
{
if (i_sBaseFilename == null) i_sBaseFilename = msc_sBaseFilename;
string[] asFiles = null;
try
{
asFiles = System.IO.Directory.GetFiles(i_sPath, i_sBaseFilename + "_*.xml");
}
catch { return; }
ms_dictCultureExceptionMessages.Clear();
for (int ixFile = 0; ixFile < asFiles.Length; ixFile++)
{
string sXmlPathFilename = asFiles[ixFile];
XmlDocument xmldoc = new XmlDocument();
try
{
xmldoc.Load(sXmlPathFilename);
XmlNode xmlnodeRoot = xmldoc.SelectSingleNode("/" + msc_sXmlGroup_Root);
string sCulture = xmlnodeRoot.SelectSingleNode(msc_sXmlGroup_Info + "/" + msc_sXmlData_Culture).Value;
CultureInfo oCultureInfo = new CultureInfo(sCulture);
XmlNode xmlnodeMessages = xmlnodeRoot.SelectSingleNode(msc_sXmlGroup_Messages);
XmlNodeList xmlnodelistMessage = xmlnodeMessages.ChildNodes;
Dictionary<string, string> dictExceptionMessage = new Dictionary<string, string>(xmlnodelistMessage.Count + 10);
for (int ixNode = 0; ixNode < xmlnodelistMessage.Count; ixNode++)
dictExceptionMessage.Add(xmlnodelistMessage[ixNode].Name, xmlnodelistMessage[ixNode].InnerText);
ms_dictCultureExceptionMessages.Add(oCultureInfo, dictExceptionMessage);
}
catch
{ return; }
}
}
//----------------------------------------------------------------------------
// SaveMessagesToXML
//----------------------------------------------------------------------------
public static void SaveMessagesToXML(string i_sPath, string i_sBaseFilename)
{
if (i_sBaseFilename == null) i_sBaseFilename = msc_sBaseFilename;
foreach (KeyValuePair<CultureInfo, Dictionary<string, string>> kvpCultureExceptionMessages in ms_dictCultureExceptionMessages)
{
string sXmlPathFilename = i_sPath + i_sBaseFilename + "_" + kvpCultureExceptionMessages.Key.TwoLetterISOLanguageName + ".xml";
Dictionary<string, string> dictExceptionMessage = kvpCultureExceptionMessages.Value;
XmlDocument xmldoc = new XmlDocument();
XmlWriter xmlwriter = null;
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
try
{
XmlNode xmlnodeRoot = xmldoc.CreateElement(msc_sXmlGroup_Root);
xmldoc.AppendChild(xmlnodeRoot);
XmlNode xmlnodeInfo = xmldoc.CreateElement(msc_sXmlGroup_Info);
XmlNode xmlnodeMessages = xmldoc.CreateElement(msc_sXmlGroup_Messages);
xmlnodeRoot.AppendChild(xmlnodeInfo);
xmlnodeRoot.AppendChild(xmlnodeMessages);
XmlNode xmlnodeCulture = xmldoc.CreateElement(msc_sXmlData_Culture);
xmlnodeCulture.InnerText = kvpCultureExceptionMessages.Key.Name;
xmlnodeInfo.AppendChild(xmlnodeCulture);
foreach (KeyValuePair<string, string> kvpExceptionMessage in dictExceptionMessage)
{
XmlNode xmlnodeMsg = xmldoc.CreateElement(kvpExceptionMessage.Key);
xmlnodeMsg.InnerText = kvpExceptionMessage.Value;
xmlnodeMessages.AppendChild(xmlnodeMsg);
}
xmlwriter = XmlWriter.Create(sXmlPathFilename, writerSettings);
xmldoc.WriteTo(xmlwriter);
}
catch (Exception e)
{ return; }
finally
{ if (xmlwriter != null) xmlwriter.Close(); }
}
}
//----------------------------------------------------------------------------
// CreateMessagesInThread
//----------------------------------------------------------------------------
private static void CreateMessagesInThread()
{
Thread.CurrentThread.Name = "CException.CreateMessagesInThread";
Dictionary<string, string> dictExceptionMessage = new Dictionary<string, string>(0x1000);
GetExceptionMessages(dictExceptionMessage);
GetExceptionMessagesWin32(dictExceptionMessage);
ms_dictCultureExceptionMessages.Add(Thread.CurrentThread.CurrentUICulture, dictExceptionMessage);
}
//----------------------------------------------------------------------------
// GetExceptionTypes
//----------------------------------------------------------------------------
private static List<Type> GetExceptionTypes()
{
Assembly[] aoAssembly = AppDomain.CurrentDomain.GetAssemblies();
List<Type> listoExceptionType = new List<Type>();
Type oExceptionType = typeof(Exception);
for (int ixAssm = 0; ixAssm < aoAssembly.Length; ixAssm++)
{
if (!aoAssembly[ixAssm].GlobalAssemblyCache) continue;
Type[] aoType = aoAssembly[ixAssm].GetTypes();
for (int ixType = 0; ixType < aoType.Length; ixType++)
{
if (aoType[ixType].IsSubclassOf(oExceptionType))
listoExceptionType.Add(aoType[ixType]);
}
}
return listoExceptionType;
}
//----------------------------------------------------------------------------
// GetExceptionMessages
//----------------------------------------------------------------------------
private static void GetExceptionMessages(Dictionary<string, string> i_dictExceptionMessage)
{
List<Type> listoExceptionType = GetExceptionTypes();
for (int ixException = 0; ixException < listoExceptionType.Count; ixException++)
{
Type oExceptionType = listoExceptionType[ixException];
string sExceptionName = MakeXMLCompliant(oExceptionType.FullName);
try
{
if (i_dictExceptionMessage.ContainsKey(sExceptionName))
continue;
Exception e = (Exception)(Activator.CreateInstance(oExceptionType));
i_dictExceptionMessage.Add(sExceptionName, e.Message);
}
catch (Exception)
{ i_dictExceptionMessage.Add(sExceptionName, null); }
}
}
//----------------------------------------------------------------------------
// GetExceptionMessagesWin32
//----------------------------------------------------------------------------
private static void GetExceptionMessagesWin32(Dictionary<string, string> i_dictExceptionMessage)
{
string sTypeName = MakeXMLCompliant(typeof(Win32Exception).FullName) + "_";
for (int iError = 0; iError < 0x4000; iError++) // Win32 errors may range from 0 to 0xFFFF
{
Exception e = new Win32Exception(iError);
if (!e.Message.StartsWith("Unknown error (", StringComparison.OrdinalIgnoreCase))
i_dictExceptionMessage.Add(sTypeName + iError, e.Message);
}
}
//----------------------------------------------------------------------------
// CreateMessage
//----------------------------------------------------------------------------
private static string CreateMessage(Exception i_oException, CultureInfo i_oCultureInfo)
{
CException oEx = new CException(i_oException, i_oCultureInfo);
Thread oTH = new Thread(new ParameterizedThreadStart(CreateMessageInThread));
oTH.Start(oEx);
while (oTH.IsAlive)
{ Thread.Sleep(10); }
return oEx.m_sMessage;
}
//----------------------------------------------------------------------------
// CreateMessageInThread
//----------------------------------------------------------------------------
private static void CreateMessageInThread(Object i_oData)
{
if (i_oData == null) return;
CException oEx = (CException)i_oData;
if (oEx.m_oException == null) return;
Thread.CurrentThread.CurrentUICulture = oEx.m_oCultureInfo == null ? CultureInfo.InvariantCulture : oEx.m_oCultureInfo;
// create new exception in desired culture
Exception e = null;
Win32Exception oWin32Exception = (Win32Exception)(oEx.m_oException);
if (oWin32Exception != null)
e = new Win32Exception(oWin32Exception.NativeErrorCode);
else
{
try
{
e = (Exception)(Activator.CreateInstance(oEx.m_oException.GetType()));
}
catch { }
}
if (e != null)
oEx.m_sMessage = e.Message;
}
//----------------------------------------------------------------------------
// MakeXMLCompliant
// from https://www.w3.org/TR/xml/
//----------------------------------------------------------------------------
private static string MakeXMLCompliant(string i_sName)
{
if (string.IsNullOrEmpty(i_sName))
return "_";
System.Text.StringBuilder oSB = new System.Text.StringBuilder();
for (int ixChar = 0; ixChar < (i_sName == null ? 0 : i_sName.Length); ixChar++)
{
char character = i_sName[ixChar];
if (IsXmlNodeNameCharacterValid(ixChar, character))
oSB.Append(character);
}
if (oSB.Length <= 0)
oSB.Append("_");
return oSB.ToString();
}
//----------------------------------------------------------------------------
private static bool IsXmlNodeNameCharacterValid(int i_ixPos, char i_character)
{
if (i_character == ':') return true;
if (i_character == '_') return true;
if (i_character >= 'A' && i_character <= 'Z') return true;
if (i_character >= 'a' && i_character <= 'z') return true;
if (i_character >= 0x00C0 && i_character <= 0x00D6) return true;
if (i_character >= 0x00D8 && i_character <= 0x00F6) return true;
if (i_character >= 0x00F8 && i_character <= 0x02FF) return true;
if (i_character >= 0x0370 && i_character <= 0x037D) return true;
if (i_character >= 0x037F && i_character <= 0x1FFF) return true;
if (i_character >= 0x200C && i_character <= 0x200D) return true;
if (i_character >= 0x2070 && i_character <= 0x218F) return true;
if (i_character >= 0x2C00 && i_character <= 0x2FEF) return true;
if (i_character >= 0x3001 && i_character <= 0xD7FF) return true;
if (i_character >= 0xF900 && i_character <= 0xFDCF) return true;
if (i_character >= 0xFDF0 && i_character <= 0xFFFD) return true;
// if (i_character >= 0x10000 && i_character <= 0xEFFFF) return true;
if (i_ixPos > 0)
{
if (i_character == '-') return true;
if (i_character == '.') return true;
if (i_character >= '0' && i_character <= '9') return true;
if (i_character == 0xB7) return true;
if (i_character >= 0x0300 && i_character <= 0x036F) return true;
if (i_character >= 0x203F && i_character <= 0x2040) return true;
}
return false;
}
private static string msc_sBaseFilename = "exception_messages";
private static string msc_sXmlGroup_Root = "exception_messages";
private static string msc_sXmlGroup_Info = "info";
private static string msc_sXmlGroup_Messages = "messages";
private static string msc_sXmlData_Culture = "culture";
private Exception m_oException;
private CultureInfo m_oCultureInfo;
private string m_sMessage;
static Dictionary<CultureInfo, Dictionary<string, string>> ms_dictCultureExceptionMessages = new Dictionary<CultureInfo, Dictionary<string, string>>();
}
internal class Program
{
public static void Main()
{
CException.CreateMessages(null);
CException.SaveMessagesToXML(@"d:\temp\", "emsg");
CException.LoadMessagesFromXML(@"d:\temp\", "emsg");
}
}
이것은 저에게 효과가 있었습니다.
//Exception Class Extensions
public static class ExceptionExtensions
{
public static string EnMessage(this Exception ex)
{
CultureInfo oldCI = Thread.CurrentThread.CurrentCulture;
string englishExceptionMessage = ex.Message;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
try
{
var objectType = Type.GetType(ex.GetType().FullName);
var instantiatedObject = Activator.CreateInstance(objectType);
throw (Exception)instantiatedObject;
}
catch (Exception e)
{
englishExceptionMessage = e.Message;
}
Thread.CurrentThread.CurrentCulture = oldCI;
Thread.CurrentThread.CurrentUICulture = oldCI;
return englishExceptionMessage;
}
}
그런 다음 새 메소드를 ex로 호출하여 사용할 수 있습니다.EnMessage();
IIS를 변경해야 했습니다.거기서 IIS 관리자 > 사이트 선택 > .NET 글로벌화 > UI 문화를 영어로 설정합니다.
.NET Core 이상과 관련하여 의 문서에서는 이 속성을 사용하여 현재 문화를 검색하고 설정할 것을 권장합니다.
CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;
관련 깃허브 문제와 관련하여 Tarek Mahmoud Sayed는 나중에 다른 스레드도 동일한 문화를 얻을 수 있도록 사용할 것을 권고했습니다.
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
후자는 .NET Framework 4.5(및 .NET Core 1.0) 이후에만 사용할 수 있습니다.
이 확장 메서드는 때때로 작동할 수 있지만 모든 경우에는 작동하지 않습니다.
public static string GetEnglishExceptionMessage(this Exception exception)
{
// Get the culture info for the current thread
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
// Create a new culture info for en-US
CultureInfo englishCulture = new CultureInfo("en-US");
// Change the current thread's culture to en-US
Thread.CurrentThread.CurrentCulture = englishCulture;
// Get the english version of the exception message from the c# standard library
string englishExceptionMessage = System.Runtime.InteropServices.Marshal.GetExceptionForHR(exception.HResult).Message;
// Reset the current thread's culture to the original culture
Thread.CurrentThread.CurrentCulture = currentCulture;
// Return the english version of the exception message
return englishExceptionMessage;
}
안타깝게도 잘못된 결과를 반환하는 경우가 있습니다.예: 인수예외는 작동하지만 HttpRequest예외는 그렇지 않습니다.
다음과 같은 방식으로 사용할 수 있습니다.
var error = new NullReferenceException("This is a Test String");
string NonLocalMessage = error.GetEnglishExceptionMessage();
오류 메시지(IIRC, 단순 예외) 대신 통화 스택을 기록해야 합니다.ToString()이 이 작업을 수행해야 합니다.여기서 예외가 발생한 위치를 정확히 확인하고 일반적으로 예외가 어떤 것인지 추론할 수 있습니다.
확장 메서드를 사용하여 캐치 블록의 예외 메시지를 재정의합니다. 아래에 언급된 것처럼 메시지가 코드에서 왔는지 여부를 확인하십시오.
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();
}
로깅을 위해 특정 응용프로그램은 영어 예외 메시지를 가져와야 할 수 있습니다(일반적인 클라이언트의 UICulture에 메시지를 표시하는 것 외에도).
그 목적을 위해, 다음의 코드.
- 현재 UICulture를 변경합니다.
- "GetType()" 및 "Activator"를 사용하여 던져진 예외 개체를 다시 만듭니다.인스턴스(t) 만들기"
- 새 UICure에 새 예외 개체의 메시지를 표시합니다.
그런 다음 마지막으로 현재 UI 문화를 이전 UI 문화로 다시 변경합니다.
try { int[] a = { 3, 6 }; Console.WriteLine(a[3]); //Throws index out of bounds exception System.IO.StreamReader sr = new System.IO.StreamReader(@"c:\does-not-exist"); // throws file not found exception throw new System.IO.IOException(); } catch (Exception ex) { Console.WriteLine(ex.Message); Type t = ex.GetType(); CultureInfo CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US"); object o = Activator.CreateInstance(t); System.Threading.Thread.CurrentThread.CurrentUICulture = CurrentUICulture; // Changing the UICulture back to earlier culture Console.WriteLine(((Exception)o).Message.ToString()); Console.ReadLine(); }
예외 메시지(영어)
try
{
......
}
catch (Exception ex)
{
throw new UserFriendlyException(L("ExceptionmessagesinEnglish"));
}
그런 다음 Localization 폴더로 이동하여 projectName.xml에 배치하고 추가합니다.
<text name="ExceptionmessagesinEnglish">Exception Message in English</text>
언급URL : https://stackoverflow.com/questions/209133/exception-messages-in-english
'it-source' 카테고리의 다른 글
버튼 또는 레이블 텍스트에서 "&"(앰퍼샌드)를 표시하려면 어떻게 해야 합니까? (0) | 2023.05.26 |
---|---|
Azure 사용자 지정 컨트롤러 / API.네트 백엔드 (0) | 2023.05.21 |
mongodb에 대한 연결을 확인하는 방법 (0) | 2023.05.21 |
브라우저가 요청을 취소하는 경우 ASP.NET Web API OperationCancelledException (0) | 2023.05.21 |
SQL Server와 같은 join in from 절을 사용하여 select 절에서 Postgresql 하위 쿼리를 수행하는 방법은 무엇입니까? (0) | 2023.05.21 |