c# - 从 ArgumentException 中获取原始错误消息
问题描述
在.Net 中编写用于内部处理的类时,我经常用它ArgumentException
来表示给定数据有问题并且无法处理。由于程序的性质,我在这些异常中输入的文本有时与用户相关,因此它经常显示在 UI 上。
但是,我注意到它ArgumentException
专门覆盖了Message
属性以附加它自己的字符串来指示哪个参数导致了异常。我不希望这个额外的文本污染消息,因为实际的参数名称是内部处理信息,实际上不需要向用户显示,而且它添加了一个换行符,而且它是本地化的,一团糟设置我在 UI 上显示的消息的格式。解决这个问题的唯一方法是不给异常提供实际的参数名称,但我也不想通过删除该信息来破坏我自己的调试/日志记录。
当然,我可以使用我自己的异常类,但由于这些方法中有很多是用于压缩和解压缩旧 DOS 游戏中的专有文件格式,我希望这些方法都记录在 wiki 上,并且通常易于使用其他任何人,我宁愿保持它们的可移植性并避免依赖其他外部类。而且,作为旁注,子类ArgumentException
化当然会产生同样的问题。
原始来源:
public override String Message
{
get {
String s = base.Message;
if (!String.IsNullOrEmpty(m_paramName)) {
String resourceString = Environment.GetResourceString("Arg_ParamName_Name", m_paramName);
return s + Environment.NewLine + resourceString;
}
else
return s;
}
}
(来自referencesource.microsoft.com)
由于这实际上覆盖了该Message
属性,因此似乎没有正常的方法可以获取内部存储的真实消息。根据本地化差异(并且我给它的消息可能已经有换行符),在换行符处拆分似乎很混乱并且可能不可靠,并且为此使用反射似乎相当混乱。有没有一种干净的方法来恢复原始消息?
(出于记录原因,在此处发布此解决方案,因为当我遇到这种行为时,我真的很沮丧)
解决方案
因为我不想深入研究反射,所以我想出一个在没有相关类行为的情况下获取原始数据的好方法是序列化它。序列化信息中的属性名称非常简单,可以在没有ArgumentException
getter 自己添加的情况下对其进行访问。
实现这一点的代码非常简单:
public static String RecoverArgExceptionMessage(ArgumentException argex)
{
if (argex == null)
return null;
SerializationInfo info = new SerializationInfo(typeof(ArgumentException), new FormatterConverter());
argex.GetObjectData(info, new StreamingContext(StreamingContextStates.Clone));
return info.GetString("Message");
}
推荐阅读
- java - Java - 直接在 AWS S3 存储桶中将 word 转换为 pdf,而无需在本地下载
- outlook-addin - Outlook 2016 缓存加载项图像多长时间?
- spring - Spring Security:AuthenticationProvider 和 UserDetailsService 之间的链接
- sql - 如何在 postgres 中计算每天的不同时间戳?
- node.js - E503 发布 NPM 时发现错误。我该如何解决?
- ios - 设置音频输入增益音量/麦克风输入音量iOS14
- scala - 无法运行树高 scala 代码
- python - 通过在另一个表中排名来排序 Matplotlib 上的图例?
- javascript - 输入给出“空值”
- xamarin.forms - 按钮 ContentLayout 不起作用 [Xamarin 5.0,Android 10]