У меня есть несколько Exception
производных типов, которые добавляют дополнительные свойства к Exception
. Поиск в Интернете примеров и рекомендаций о том, как обрабатывать сериализацию таких Exception
типов, привел к описаниям и образцам кода, которые были довольно старыми. Использование этих примеров всегда приводило к ошибкам безопасности. Чтобы это работало, мне пришлось дополнительно декорировать GetObjectData
-Metod с атрибутом System.Security.SecurityCritical
.
Интересно, что SecurityPermission
-Атрибут, который содержался во всех примерах, но в различных пути, казалось, не нужны. Некоторые примеры только добавили его в GetObjectData
, некоторые добавили также в конструктор десериализации. В некоторых примерах использовалось сильное действие SecurityAction.Demand
, в большинстве примеров использовалось действие SecurityAction.LinkDemand
, в других - SecurityAction.RequestMinimum
.
Мой вопрос заключается в том, является ли правильный тип, полученный ниже Exception
(для части сериализации), правильным для использования в настоящее время. net frameworks (4.7. [X] +, Core [x] ], Standard2. [X] +) или если чего-то не хватает, или я могу даже удалить некоторые детали? Обратите внимание, что я не хочу запечатывать тип. Другие Exception
-типы должны иметь возможность наследования от него.
[Serializable]
public class FooException : Exception{
readonly int m_fooValue;
public FooException(string message,int fooValue,Exception innerException=null) : base(message,innerException){
m_fooValue = fooValue;
}
[SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
protected FooException(SerializationInfo info, StreamingContext context) : base(info, context) {
m_fooValue = info.GetInt32(nameof(FooValue));
}
[SecurityCritical]
[SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) throw new ArgumentNullException(nameof(info));
info.AddValue(nameof(FooValue), m_fooValue);
base.GetObjectData(info, context);
}
public int FooValue => m_fooValue;
}
Производный тип (FooBarException
) дополнительно должен также установить атрибут SecurityCritical
в конструкторе deserializung для удовлетворения LinkDemand
:
[Serializable]
public class FooBarException : FooException{
readonly int m_barValue;
public FooBarException(string message,int fooValue, int barValue, Exception innerException = null) : base(message, fooValue, innerException) {
m_barValue = barValue;
}
[SecurityCritical] // Additional for satisfying the LinkDemand on the base constructor
[SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
protected FooBarException(SerializationInfo info, StreamingContext context) : base(info, context) {
m_barValue = info.GetInt32(nameof(BarValue));
}
[SecurityCritical]
[SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) throw new ArgumentNullException(nameof(info));
info.AddValue(nameof(BarValue), m_barValue);
base.GetObjectData(info, context);
}
public int BarValue => m_barValue;
}
Источники
{ ссылка }
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.iserializable.getobjectdata?view=netframework-4.8
Как правильно создать заказ. NET Сериализуемое исключение?
https://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/