Sdílet prostřednictvím


Zdroj události BinaryFormatter

Počínaje rozhraním .NET 5 obsahuje předdefinovaný EventSource modul, který poskytuje přehled o tom, BinaryFormatter kdy dochází k serializaci nebo deserializaci objektu. Aplikace můžou pomocí EventListenerodvozených typů naslouchat těmto oznámením a protokolovat je.

Tato funkce není náhradou za nebo SerializationBinderISerializationSurrogate a nelze ji použít k úpravě dat serializovaných nebo deserializovaných. Tento systém událostí je spíše určen k poskytnutí přehledu o typech serializovaných nebo deserializovaných. Dá se také použít ke zjišťování nechtěných volání do BinaryFormatter infrastruktury, například volání pocházejících z kódu knihovny třetích stran.

Popis událostí

Zdroj BinaryFormatter události má dobře známý název System.Runtime.Serialization.Formatters.Binary.BinaryFormatterEventSource. Naslouchací procesy se můžou přihlásit k odběru šesti událostí.

SerializationStart – událost (id = 10)

Vyvolána, když BinaryFormatter.Serialize byla volána a spustila proces serializace. Tato událost je spárovaná s událostí SerializationEnd . Událost SerializationStart může být volána rekurzivně, pokud objekt volá BinaryFormatter.Serialize v rámci své vlastní serializace rutiny.

Tato událost neobsahuje datovou část.

SerializationEnd – událost (id = 11)

Vyvolá se po BinaryFormatter.Serialize dokončení práce. Každý výskyt SerializationEnd označuje dokončení poslední nespárové SerializationStart události.

Tato událost neobsahuje datovou část.

SerializingObject – událost (id = 12)

Vyvolána, když BinaryFormatter.Serialize je v procesu serializace neprimitivního typu. Infrastruktura BinaryFormatter speciální případy určitých typů (například string a int) a nevyvolá tuto událost, pokud jsou tyto typy nalezeny. Tato událost je vyvolána pro uživatelem definované typy a další typy, kterým BinaryFormatter nativně nerozumí.

Tato událost může být vyvolána nula nebo vícekrát mezi událostmi SerializationStart a SerializationEnd .

Tato událost obsahuje datovou část s jedním argumentem:

Událost DeserializationStart (id = 20)

Vyvolána při BinaryFormatter.Deserialize zavolání a zahájení procesu deserializace. Tato událost je spárovaná s událostí DeserializationEnd . Událost DeserializationStart může být volána rekurzivně, pokud objekt volá BinaryFormatter.Deserialize v rámci své vlastní rutiny deserializace.

Tato událost neobsahuje datovou část.

Událost DeserializationEnd (id = 21)

Vyvolá se po BinaryFormatter.Deserialize dokončení práce. Každý výskyt DeserializationEnd označuje dokončení poslední nespárové DeserializationStart události.

Tato událost neobsahuje datovou část.

Událost DeserializingObject (id = 22)

Vyvolána, když BinaryFormatter.Deserialize je v procesu deserializace neprimitivního typu. Infrastruktura BinaryFormatter speciální případy určitých typů (například string a int) a nevyvolá tuto událost, pokud jsou tyto typy nalezeny. Tato událost je vyvolána pro uživatelem definované typy a další typy, kterým BinaryFormatter nativně nerozumí.

Tato událost může být vyvolána nula nebo vícekrát mezi událostmi DeserializationStart a DeserializationEnd .

Tato událost obsahuje datovou část s jedním argumentem.

[Upřesnit] Přihlášení k odběru podmnožině oznámení

Naslouchací procesy, které se chtějí přihlásit k odběru jenom podmnožina oznámení, můžou zvolit, která klíčová slova se mají povolit.

  • Serialization = (EventKeywords)1: Vyvolá SerializationStartudálosti , SerializationEnda SerializingObject .
  • Deserialization = (EventKeywords)2: Vyvolá DeserializationStartudálosti , DeserializationEnda DeserializingObject .

Pokud během EventListener registrace nejsou k dispozici žádné filtry klíčových slov, jsou vyvolány všechny události.

Další informace naleznete v tématu System.Diagnostics.Tracing.EventKeywords.

Ukázka kódu

Následující kód:

  • vytvoří odvozený EventListenertyp, který zapisuje do System.Console,
  • přihlásí tento naslouchací proces k BinaryFormatteroznámením vytvořeným,
  • serializuje a deserializuje jednoduchý objektový graf pomocí BinaryFormattera
  • analyzuje události, které byly vyvolány.
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]}");
                }
            }
        }
    }
}

Předchozí kód vytvoří výstup podobný následujícímu příkladu:

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

V této ukázce protokoly založené na EventListener konzole, které serializace spustí, instance Person a Book jsou serializovány a pak serializace dokončena. Podobně po zahájení deserializace jsou instance Person a Book deserializovány a poté se deserializace dokončí.

Aplikace pak vytiskne hodnoty obsažené v deserializovaném Person objektu, aby ukázala, že objekt ve skutečnosti serializoval a deserializoval správně.

Viz také

Další informace o používání EventListener k příjmu EventSourceoznámení založených na této třídě najdete v EventListener tématu .