Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Począwszy od platformy .NET 5, BinaryFormatter zawiera wbudowaną funkcję EventSource , która zapewnia wgląd w proces serializacji lub deserializacji obiektów. Aplikacje mogą używać EventListenertypów pochodnych do nasłuchiwania tych powiadomień i rejestrowania ich.
Ta funkcja nie jest substytutem elementu SerializationBinder lub i ISerializationSurrogate nie może być używana do modyfikowania danych serializacji lub deserializacji. Zamiast tego ten system zdarzeń ma na celu zapewnienie wglądu w typy serializowane lub deserializowane. Można go również użyć do wykrywania niezamierzonych wywołań w BinaryFormatter infrastrukturze, takich jak wywołania pochodzące z kodu biblioteki innej firmy.
Opis zdarzeń
Źródło BinaryFormatter zdarzeń ma dobrze znaną nazwę System.Runtime.Serialization.Formatters.Binary.BinaryFormatterEventSource. Odbiorniki mogą subskrybować sześć zdarzeń.
Zdarzenie SerializationStart (id = 10)
Podniesione po BinaryFormatter.Serialize wywołaniu i rozpoczęto proces serializacji. To zdarzenie jest sparowane ze zdarzeniem SerializationEnd . Zdarzenie SerializationStart może być wywoływane rekursywnie, jeśli obiekt wywołuje BinaryFormatter.Serialize własną procedurę serializacji.
To zdarzenie nie zawiera ładunku.
Zdarzenie SerializationEnd (id = 11)
Podniesione, gdy BinaryFormatter.Serialize zakończyło swoją pracę. Każde wystąpienie SerializationEnd oznacza zakończenie ostatniego niespłaconego SerializationStart zdarzenia.
To zdarzenie nie zawiera ładunku.
SerializingObject event (id = 12)
Podniesione, gdy BinaryFormatter.Serialize jest w trakcie serializacji typu innego niż pierwotny. Specjalne BinaryFormatter przypadki infrastruktury niektórych typów (takich jak string i int) i nie zgłasza tego zdarzenia, gdy te typy zostaną napotkane. To zdarzenie jest wywoływane dla typów zdefiniowanych przez użytkownika i innych typów, które BinaryFormatter nie rozumieją natywnie.
To zdarzenie może zostać podniesione zero lub więcej razy między zdarzeniami SerializationStart i SerializationEnd .
To zdarzenie zawiera ładunek z jednym argumentem:
typeName(string): nazwa kwalifikowana przez zestaw (patrz Type.AssemblyQualifiedName) typu serializowanego.
DeserializationStart zdarzenie (id = 20)
Podniesione po BinaryFormatter.Deserialize wywołaniu i rozpoczęto proces deserializacji. To zdarzenie jest sparowane ze zdarzeniem DeserializationEnd . Zdarzenie DeserializationStart może być wywoływane rekursywnie, jeśli obiekt wywołuje BinaryFormatter.Deserialize własną procedurę deserializacji.
To zdarzenie nie zawiera ładunku.
Zdarzenie deserializationEnd (id = 21)
Podniesione, gdy BinaryFormatter.Deserialize zakończyło swoją pracę. Każde wystąpienie DeserializationEnd oznacza zakończenie ostatniego niespłaconego DeserializationStart zdarzenia.
To zdarzenie nie zawiera ładunku.
Zdarzenie DeserializingObject (id = 22)
Podniesione, gdy BinaryFormatter.Deserialize jest w procesie deserializacji typu nie-pierwotnego. Specjalne BinaryFormatter przypadki infrastruktury niektórych typów (takich jak string i int) i nie zgłasza tego zdarzenia, gdy te typy zostaną napotkane. To zdarzenie jest wywoływane dla typów zdefiniowanych przez użytkownika i innych typów, które BinaryFormatter nie rozumieją natywnie.
To zdarzenie może zostać podniesione zero lub więcej razy między zdarzeniami DeserializationStart i DeserializationEnd .
To zdarzenie zawiera ładunek z jednym argumentem.
typeName(string): Kwalifikowana nazwa zestawu (patrz Type.AssemblyQualifiedName) typu deserializowanego.
[Zaawansowane] Subskrybowanie podzestawu powiadomień
Odbiorniki, które chcą subskrybować tylko podzestaw powiadomień, mogą wybrać słowa kluczowe do włączenia.
Serialization=(EventKeywords)1: zgłaszaSerializationStartzdarzenia ,SerializationEndiSerializingObject.Deserialization=(EventKeywords)2: zgłaszaDeserializationStartzdarzenia ,DeserializationEndiDeserializingObject.
Jeśli podczas rejestracji nie są udostępniane EventListener żadne filtry słów kluczowych, wszystkie zdarzenia są zgłaszane.
Aby uzyskać więcej informacji, zobacz System.Diagnostics.Tracing.EventKeywords.
Przykładowy kod
Następujący kod powoduje:
EventListenertworzy typ pochodny, który zapisuje w obiekcieSystem.Console,- subskrybuje ten odbiornik do
BinaryFormatter-wygenerowanych powiadomień, - serializuje i deserializuje prosty graf obiektu przy użyciu metody
BinaryFormatteri - analizuje zgłoszone zdarzenia.
using System;
using System.Diagnostics.Tracing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace BinaryFormatterEventSample
{
class Program
{
static EventListener? _globalListener = null;
static void Main(string[] args)
{
// First, set up the event listener.
// Note: We assign it to a static field so that it doesn't get GCed.
// We also provide a callback that subscribes this listener to all
// events produced by the well-known BinaryFormatter source.
_globalListener = new ConsoleEventListener();
_globalListener.EventSourceCreated += (sender, args) =>
{
if (args.EventSource?.Name ==
"System.Runtime.Serialization.Formatters.Binary.BinaryFormatterEventSource")
{
((EventListener?)sender)?
.EnableEvents(args.EventSource, EventLevel.LogAlways);
}
};
// Next, create the Person object and serialize it.
Person originalPerson = new Person()
{
FirstName = "Logan",
LastName = "Edwards",
FavoriteBook = new Book()
{
Title = "A Tale of Two Cities",
Author = "Charles Dickens",
Price = 10.25m
}
};
byte[] serializedPerson = SerializePerson(originalPerson);
// Finally, deserialize the Person object.
Person rehydratedPerson = DeserializePerson(serializedPerson);
Console.WriteLine
($"Rehydrated person {rehydratedPerson.FirstName} {rehydratedPerson.LastName}");
Console.Write
($"Favorite book: {rehydratedPerson.FavoriteBook?.Title} ");
Console.Write
($"by {rehydratedPerson.FavoriteBook?.Author}, ");
Console.WriteLine
($"list price {rehydratedPerson.FavoriteBook?.Price}");
}
private static byte[] SerializePerson(Person p)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
#pragma warning disable SYSLIB0011 // BinaryFormatter.Serialize is obsolete
formatter.Serialize(memStream, p);
#pragma warning restore SYSLIB0011
return memStream.ToArray();
}
private static Person DeserializePerson(byte[] serializedData)
{
MemoryStream memStream = new MemoryStream(serializedData);
BinaryFormatter formatter = new BinaryFormatter();
#pragma warning disable SYSLIB0011 // Danger: BinaryFormatter.Deserialize is insecure for untrusted input
return (Person)formatter.Deserialize(memStream);
#pragma warning restore SYSLIB0011
}
}
[Serializable]
public class Person
{
public string? FirstName;
public string? LastName;
public Book? FavoriteBook;
}
[Serializable]
public class Book
{
public string? Title;
public string? Author;
public decimal? Price;
}
// A sample EventListener that writes data to System.Console.
public class ConsoleEventListener : EventListener
{
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
base.OnEventWritten(eventData);
Console.WriteLine($"Event {eventData.EventName} (id={eventData.EventId}) received.");
if (eventData.PayloadNames != null)
{
for (int i = 0; i < eventData.PayloadNames.Count; i++)
{
Console.WriteLine($"{eventData.PayloadNames[i]} = {eventData.Payload?[i]}");
}
}
}
}
}
Powyższy kod generuje dane wyjściowe podobne do następującego przykładu:
Event SerializationStart (id=10) received.
Event SerializingObject (id=12) received.
typeName = BinaryFormatterEventSample.Person, BinaryFormatterEventSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Event SerializingObject (id=12) received.
typeName = BinaryFormatterEventSample.Book, BinaryFormatterEventSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Event SerializationStop (id=11) received.
Event DeserializationStart (id=20) received.
Event DeserializingObject (id=22) received.
typeName = BinaryFormatterEventSample.Person, BinaryFormatterEventSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Event DeserializingObject (id=22) received.
typeName = BinaryFormatterEventSample.Book, BinaryFormatterEventSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Event DeserializationStop (id=21) received.
Rehydrated person Logan Edwards
Favorite book: A Tale of Two Cities by Charles Dickens, list price 10.25
W tym przykładzie dzienniki oparte na EventListener konsoli uruchamiają serializacji, wystąpienia i PersonBook są serializowane, a następnie kończy serializacji. Podobnie, po rozpoczęciu deserializacji wystąpienia Person i Book są deserializowane, a następnie deserializacja zostanie ukończona.
Następnie aplikacja wyświetla wartości zawarte w deserializacji Person , aby pokazać, że obiekt rzeczywiście serializował i deserializował prawidłowo.
Zobacz też
Aby uzyskać więcej informacji na temat odbierania EventListenerEventSourcepowiadomień opartych na użyciu, zobacz klasęEventListener.