Exception
はISerializable
とJson.NET supports this interfaceを実装しているため、これが起こっていることは間違いありません。
info.AddValue("Message", _message, typeof(String));
Message
プロパティが基になるフィールド場合は、デフォルト値を持っているため、Microsoftはこれを行っていることがあります。具体的には、参照元から、方法Exception.GetObjectData(SerializationInfo info, StreamingContext context)
で、Exception
タイプは、基礎となるフィールド、ないプロパティをシリアライズ設定されていない。
public virtual String Message {
get {
if (_message == null) {
if (_className==null) {
_className = GetClassName();
}
return Environment.GetResourceString("Exception_WasThrown", _className);
} else {
return _message;
}
}
}
フィールドをシリアル化することではなく、プロパティ、デフォルトのメッセージで例外が逆シリアル化するとき、その目に見えるメッセージを自動的に受信システムのCurrentUICulture
に示されているであろう。
したがって、メッセージプロパティの値を、基礎となるフィールドの代わりにJSONに表示するには、GetObjectData()
をオーバーライドする必要があります。また、既存の値と同じ名前の値を追加しようとするとAddValue()
が例外をスローするため、SerializationInfo
には現在の値を置き換えるにはSetValue()
のメソッドがありません。コードのにおい:
public class GrossException : Exception
{
public GrossException() : base("Eww, gross") { }
protected GrossException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
public class BarfException : GrossException
{
public BarfException() : base() { }
protected BarfException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public override string Message { get { return "BARF!!"; } }
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
var tempInfo = new SerializationInfo(GetType(), new FormatterConverter());
base.GetObjectData(tempInfo, context);
foreach (SerializationEntry entry in tempInfo)
{
if (entry.Name != "Message")
{
info.AddValue(entry.Name, entry.Value, entry.ObjectType);
}
}
info.AddValue("Message", Message);
}
}
あなたが見ることができるように基礎となる_message
フィールドの値は、もはや、基本クラスGrossException
によってを必要な値であることから、このソリューションは、あなたの継承階層の設計に違反していません。しかし、少なくともJSONはかなりです。
より良い解決策は、メッセージを指定することができるprotectedコンストラクタ持ってGrossException
タイプを変更することです:あなただけにしたい場合は、
public class GrossException : Exception
{
public GrossException() : base("Eww, gross") { }
protected GrossException(SerializationInfo info, StreamingContext context) : base(info, context) { }
protected GrossException(string message) : base(message) { }
}
をまたはJSONでオーバーライドされたメッセージを見ますデバッグ目的のために(たとえば、あなたが例外をログに記録しているので)、あなたはちょうどそうのような直列化ストリームにそれを追加することができます。
public class BarfException : GrossException
{
public BarfException() : base() { }
protected BarfException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public override string Message { get { return "BARF!!"; } }
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("OverriddenMessage", Message);
}
}
どちらのソリューションは、コードのにおいを回避することができます。