Přehled serializace výjimek vzdálené komunikace
Serializace založená na BinaryFormatter není bezpečná, proto pro zpracování dat nepoužívejte BinaryFormatter. Další informace o dopadech na zabezpečení najdete v tématu Rizika deserializace při použití BinaryFormatter a souvisejících typů.
Azure Service Fabric použil k serializaci výjimek BinaryFormatter. Od verze ServiceFabric v9.0 je serializace dat na základě kontraktů pro výjimky vzdálené komunikace k dispozici jako funkce výslovného souhlasu. Doporučujeme, abyste se rozhodli pro serializaci výjimek vzdálené komunikace DataContract podle kroků v tomto článku.
Podpora serializace výjimek vzdálené komunikace na základě BinaryFormatter bude v budoucnu zastaralá.
Povolení serializace kontraktů dat pro výjimky vzdálené komunikace
Poznámka
Serializace kontraktu dat pro výjimky vzdálené komunikace je k dispozici pouze pro služby vzdálené komunikace V2/V2_1.
Povolení serializace kontraktů dat pro výjimky vzdálené komunikace:
Povolte serializaci výjimek vzdálené komunikace DataContract na straně služby pomocí příkazu
FabricTransportRemotingListenerSettings.ExceptionSerializationTechnique
při vytváření vzdáleného naslouchacího procesu.Bezstavová služba
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { return new[] { new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }), "ServiceEndpointV2") }; }
Stavová služba
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }), "ServiceEndpointV2") }; }
ActorService
Pokud chcete povolit serializaci výjimek vzdálené komunikace DataContract ve službě objektu actor, přepišteCreateServiceReplicaListeners()
rozšířenímActorService
.protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }); }, "MyActorServiceEndpointV2") }; }
Pokud původní výjimka obsahuje více úrovní vnitřních výjimek, můžete řídit počet úrovní vnitřních výjimek, které mají být serializovány nastavením
FabricTransportRemotingListenerSettings.RemotingExceptionDepth
.Povolte serializaci výjimek vzdálené komunikace DataContract v klientovi pomocí při
FabricTransportRemotingSettings.ExceptionDeserializationTechnique
vytváření objektu pro vytváření klienta.Vytvoření ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
Objekt ActorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient); });
Serializace výjimky vzdálené komunikace DataContract převede výjimku na objekt přenosu dat (DTO) na straně služby. Objekt DTO se převede zpět na výjimku na straně klienta. Uživatelé se musí zaregistrovat
ExceptionConvertor
, aby mohli převést požadované výjimky na objekty DTO a naopak.Rozhraní implementuje převaděče pro následující seznam výjimek. Pokud kód služby uživatele závisí na výjimkách mimo následující seznam pro implementaci opakování a zpracování výjimek, uživatelé musí implementovat a zaregistrovat převaděče pro tyto výjimky.
- Všechny výjimky Service Fabric odvozené z
System.Fabric.FabricException
- SystemExceptions odvozené z
System.SystemException
- System.AccessViolationException
- System.AppDomainUnloadedException
- System.ArgumentException
- System.ArithmeticException
- System.ArrayTypeMismatchException
- System.BadImageFormatException
- System.CannotUnloadAppDomainException
- System.Collections.Generic.KeyNotFoundException
- System.ContextMarshalException
- System.DataMisalignedException
- System.ExecutionEngineException
- System.FormatException
- System.IndexOutOfRangeException
- System.InsufficientExecutionStackException
- System.InvalidCastException
- System.invalidoperationexception
- System.InvalidProgramException
- System.IO.InternalBufferOverflowException
- System.IO.InvalidDataException
- System.IO.IOException
- System.MemberAccessException
- System.MulticastNotSupportedException
- System.NotImplementedException
- System.NotSupportedException
- System.NullReferenceException
- System.OperationCanceledException
- System.OutOfMemoryException
- System.RankException
- System.Reflection.AmbiguousMatchException
- System.Reflection.ReflectionTypeLoadException
- System.Resources.MissingManifestResourceException
- System.Resources.MissingSatelliteAssemblyException
- System.Runtime.InteropServices.ExternalException
- System.Runtime.InteropServices.InvalidComObjectException
- System.Runtime.InteropServices.InvalidOleVariantTypeException
- System.Runtime.InteropServices.MarshalDirectiveException
- System.Runtime.InteropServices.SafeArrayRankMismatchException
- System.Runtime.InteropServices.SafeArrayTypeMismatchException
- System.Runtime.Serialization.SerializationException
- System.StackOverflowException
- System.Threading.AbandonedMutexException
- System.Threading.SemaphoreFullException
- System.Threading.SynchronizationLockException
- System.Threading.ThreadInterruptedException
- System.Threading.ThreadStateException
- System.TimeoutException
- System.TypeInitializationException
- System.TypeLoadException
- System.TypeUnloadedException
- System.UnauthorizedAccessException
- System.ArgumentNullException
- System.IO.FileNotFoundException
- System.IO.DirectoryNotFoundException
- System.ObjectDisposedException
- System.AggregateException
- Všechny výjimky Service Fabric odvozené z
Ukázková implementace převodiče na straně služby pro vlastní výjimku
Následující příklad představuje referenční IExceptionConvertor
implementaci na straně služby a klienta pro dobře známý typ výjimky , CustomException
.
Vlastní výjimka
class CustomException : Exception { public CustomException(string message, string field1, string field2) : base(message) { this.Field1 = field1; this.Field2 = field2; } public CustomException(string message, Exception innerEx, string field1, string field2) : base(message, innerEx) { this.Field1 = field1; this.Field2 = field2; } public string Field1 { get; set; } public string Field2 { get; set; } }
IExceptionConvertor
implementace na straně služby :class CustomConvertorService : Microsoft.ServiceFabric.Services.Remoting.V2.Runtime.IExceptionConvertor { public Exception[] GetInnerExceptions(Exception originalException) { return originalException.InnerException == null ? null : new Exception[] { originalException.InnerException }; } public bool TryConvertToServiceException(Exception originalException, out ServiceException serviceException) { serviceException = null; if (originalException is CustomException customEx) { serviceException = new ServiceException(customEx.GetType().FullName, customEx.Message); serviceException.ActualExceptionStackTrace = originalException.StackTrace; serviceException.ActualExceptionData = new Dictionary<string, string>() { { "Field1", customEx.Field1 }, { "Field2", customEx.Field2 }, }; return true; } return false; } }
Skutečná výjimka zjištěná během provádění vzdálené komunikace volání je předána jako vstup do TryConvertToServiceException
. Pokud je typ výjimky dobře známý, TryConvertToServiceException
měl by převést původní výjimku na ServiceException
a vrátit ji jako out parametr. Hodnota True by měla být vrácena, pokud je původní typ výjimky dobře známý a původní výjimka je úspěšně převedena na ServiceException
. V opačném případě je hodnota false.
Seznam vnitřních výjimek na aktuální úrovni by měl vrátit .GetInnerExceptions()
IExceptionConvertor
implementace na straně klienta :class CustomConvertorClient : Microsoft.ServiceFabric.Services.Remoting.V2.Client.IExceptionConvertor { public bool TryConvertFromServiceException(ServiceException serviceException, out Exception actualException) { return this.TryConvertFromServiceException(serviceException, (Exception)null, out actualException); } public bool TryConvertFromServiceException(ServiceException serviceException, Exception innerException, out Exception actualException) { actualException = null; if (serviceException.ActualExceptionType == typeof(CustomException).FullName) { actualException = new CustomException( serviceException.Message, innerException, serviceException.ActualExceptionData["Field1"], serviceException.ActualExceptionData["Field2"]); return true; } return false; } public bool TryConvertFromServiceException(ServiceException serviceException, Exception[] innerExceptions, out Exception actualException) { throw new NotImplementedException(); } }
ServiceException
se předává jako parametr spolu TryConvertFromServiceException
s převedeným parametrem innerException[s]
. Pokud je skutečný typ ServiceException.ActualExceptionType
výjimky , známý typ, měl by převodník vytvořit skutečný objekt výjimky z ServiceException
a innerException[s]
.
IExceptionConvertor
registrace na straně služby :Chcete-li zaregistrovat převodce,
CreateServiceInstanceListeners
musí být přepsán a seznamIExceptionConvertor
tříd musí být předán při vytvářeníRemotingListener
instance.Bezstavová služba
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { return new[] { new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new[] { new CustomConvertorService(), }), "ServiceEndpointV2") }; }
Stavová služba
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener(serviceContext => new FabricTransportServiceRemotingListener( serviceContext, this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new [] { new CustomConvertorService(), }), "ServiceEndpointV2") }; }
ActorService
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new List<ServiceReplicaListener> { new ServiceReplicaListener(_ => { return new FabricTransportActorServiceRemotingListener( this, new FabricTransportRemotingListenerSettings { ExceptionSerializationTechnique = FabricTransportRemotingListenerSettings.ExceptionSerialization.Default, }, exceptionConvertors: new[] { new CustomConvertorService(), }); }, "MyActorServiceEndpointV2") }; }
IExceptionConvertor
registrace na straně klienta :Chcete-li zaregistrovat převodce, musí být při vytváření
ClientFactory
instance předán seznamIExceptionConvertor
tříd.Vytvoření ServiceProxyFactory
var serviceProxyFactory = new ServiceProxyFactory( (callbackClient) => { return new FabricTransportServiceRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Vytvoření ActorProxyFactory
var actorProxyFactory = new ActorProxyFactory( (callbackClient) => { return new FabricTransportActorRemotingClientFactory( new FabricTransportRemotingSettings { ExceptionDeserializationTechnique = FabricTransportRemotingSettings.ExceptionDeserialization.Default, }, callbackClient, exceptionConvertors: new[] { new CustomConvertorClient(), }); });
Poznámka
Pokud architektura najde převéstel pro výjimku, převedená (skutečná) výjimka je zabalena uvnitř AggregateException
a vyvolána v rozhraní API vzdálené komunikace (proxy). Pokud se architektuře nepodaří najít convertor, pak ServiceException
, který obsahuje všechny podrobnosti o skutečné výjimce, je zabalen uvnitř AggregateException
a je vyvolán.
Upgrade existující služby za účelem povolení serializace kontraktů dat pro výjimky vzdálené komunikace
Existující služby musí k upgradu dodržovat následující objednávku (nejprve služba). Při nedodržení tohoto pořadí může dojít k nesprávnému chování při logice opakování a zpracování výjimek.
Implementujte třídy na straně
ExceptionConvertor
služby pro požadované výjimky, pokud existují. Aktualizujte logiku registrace vzdáleného naslouchacíhoIExceptionConvertor
procesu pomocíExceptionSerializationTechnique
a seznamu tříd. Upgradujte existující službu, aby se použily změny serializace výjimek.Implementujte třídy na straně
ExceptionConvertor
klienta pro požadované výjimky, pokud existují. Aktualizujte logiku vytváření ProxyFactory pomocíExceptionSerializationTechnique
a seznamuIExceptionConvertor
tříd. Upgradujte existujícího klienta, aby se použily změny serializace výjimek.