Visualizzatori di dati personalizzati per il debugger di Visual Studio (.NET)

Un visualizzatore fa parte dell'interfaccia utente del debugger di Visual Studio che visualizza una variabile o un oggetto in modo appropriato per il relativo tipo di dati. Ad esempio, un visualizzatore bitmap interpreta una struttura bitmap e visualizza l'elemento grafico rappresentato. Alcuni visualizzatori consentono di modificare e visualizzare i dati. Nel debugger un visualizzatore è rappresentato da un'icona VisualizerIcona forma di lente di ingrandimento. È possibile selezionare l'icona in una finestra Suggerimento dati, espressione di controllo del debugger o controllo immediato e quindi selezionare il visualizzatore appropriato per l'oggetto corrispondente.

Oltre ai visualizzatori predefiniti standard, potrebbero essere disponibili più visualizzatori per il download da Microsoft, da terze parti e dalla community. È anche possibile scrivere visualizzatori personalizzati e installarli nel debugger di Visual Studio.

Questo articolo offre una panoramica generale della creazione del visualizzatore. Per istruzioni dettagliate, vedere invece gli articoli seguenti:

Nota

I visualizzatori personalizzati non sono supportati per le app piattaforma UWP (Universal Windows Platform) (UWP) e Windows 8.x.

Panoramica

È possibile scrivere un visualizzatore personalizzato per un oggetto di qualsiasi classe gestita, ad eccezione di Object e Array.

L'architettura di un visualizzatore di debugger ha due parti:

  • Il lato debugger viene eseguito all'interno del debugger di Visual Studio e crea e visualizza l'interfaccia utente del visualizzatore.

    Poiché Visual Studio viene eseguito nel runtime di .NET Framework, questo componente deve essere scritto per .NET Framework. Per questo motivo, non è possibile scriverlo per .NET Core.

  • Il lato oggetto del debug viene eseguito all'interno del processo sottoposto a debug in Visual Studio (l'oggetto del debug). L'oggetto dati da visualizzare,ad esempio un oggetto String, esiste nel processo di debug. Il lato debug invia l'oggetto al lato debugger, che lo visualizza nell'interfaccia utente creata.

    Il runtime per cui si compila questo componente deve corrispondere a quello in cui verrà eseguito il processo di debug, ovvero .NET Framework o .NET Core.

Il lato debugger riceve l'oggetto dati da un provider di oggetti che implementa l'interfaccia IVisualizerObjectProvider . Il lato debug invia l'oggetto tramite l'origine dell'oggetto, derivato da VisualizerObjectSource.

Il provider di oggetti può anche inviare i dati all'origine oggetto, che consente di scrivere un visualizzatore in grado di modificare i dati. Eseguire l'override del provider di oggetti per comunicare con l'analizzatore di espressioni e l'origine dell'oggetto.

Il lato debug e il lato debugger comunicano tra loro tramite Stream metodi che serializzano un oggetto dati in un Stream oggetto e deserializzano di nuovo in Stream un oggetto dati.

È possibile scrivere un visualizzatore per un tipo generico solo se il tipo è un tipo aperto. Questa limitazione è identica a quella prevista quando si usa l'attributo DebuggerTypeProxy. Per informazioni dettagliate, vedere Usare l'attributo DebuggerTypeProxy.

I visualizzatori personalizzati potrebbero avere considerazioni sulla sicurezza. Vedere Considerazioni sulla sicurezza del visualizzatore.

Creare l'interfaccia utente lato debugger

Per creare l'interfaccia utente del visualizzatore sul lato debugger, creare una classe che eredita da DialogDebuggerVisualizered eseguire l'override del Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show metodo per visualizzare l'interfaccia. È possibile usare IDialogVisualizerService per visualizzare Windows Form, finestre di dialogo e controlli nel visualizzatore.

  1. Usare metodi IVisualizerObjectProvider per fornire l'oggetto visualizzato al lato debugger.

  2. Creare una classe che eredita da DialogDebuggerVisualizer.

  3. Eseguire l'override del metodo Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show per visualizzare l'interfaccia. Utilizzare IDialogVisualizerService i metodi per visualizzare Windows Form, finestre di dialogo e controlli nell'interfaccia.

  4. Applicare DebuggerVisualizerAttribute, assegnando al visualizzatore (DialogDebuggerVisualizer).

Considerazioni speciali sul lato debugger per .NET 5.0+

I visualizzatori personalizzati trasferisce i dati tra il debug e i lati del debugger tramite la serializzazione binaria usando la BinaryFormatter classe per impostazione predefinita. Tuttavia, questo tipo di serializzazione viene ridotto in .NET 5 e versioni successive a causa di problemi di sicurezza relativi alle vulnerabilità infissibili . Inoltre, è stato contrassegnato completamente obsoleto in ASP.NET Core 5 e il relativo utilizzo genererà come descritto nella documentazione di ASP.NET Core. Questa sezione descrive i passaggi da eseguire per assicurarsi che il visualizzatore sia ancora supportato in questo scenario.

  • Per motivi di compatibilità, il Show metodo sottoposto a override nella sezione precedente accetta ancora .IVisualizerObjectProvider Tuttavia, a partire da Visual Studio 2019 versione 16.10, è effettivamente di tipo IVisualizerObjectProvider2. Per questo motivo, eseguire il cast dell'oggetto objectProvider nell'interfaccia aggiornata.

  • Quando si inviano oggetti, ad esempio comandi o dati, al lato debug usare il IVisualizerObjectProvider2.Serialize metodo per passarlo a un flusso, determina il formato di serializzazione migliore da usare in base al runtime del processo di debug . Passare quindi il flusso al IVisualizerObjectProvider2.TransferData metodo .

  • Se il componente del visualizzatore lato debug deve restituire qualsiasi elemento sul lato debugger, si troverà nell'oggetto Stream restituito dal TransferData metodo . Usare il IVisualizerObjectProvider2.GetDeserializableObjectFrom metodo per ottenere un'istanza IDeserializableObject da essa ed elaborarla in base alle esigenze.

Fare riferimento alla sezione Considerazioni sul lato debug speciali per .NET 5.0+ per informazioni sulle altre modifiche necessarie sul lato debug quando si usa la serializzazione binaria non è supportata.

Nota

Per altre informazioni sul problema, vedere la guida alla sicurezza BinaryFormatter.

Creare l'origine oggetto del visualizzatore per il lato debug

Nel codice laterale del debugger modificare , DebuggerVisualizerAttributeassegnando il tipo da visualizzare (l'origine oggetto lato debug) (VisualizerObjectSource). La Target proprietà imposta l'origine dell'oggetto. Se si omette l'origine oggetto, il visualizzatore userà un'origine oggetto predefinita.

Il codice laterale del debug contiene l'origine oggetto visualizzata. L'oggetto dati può eseguire l'override dei metodi di VisualizerObjectSource. Se si vuole creare un visualizzatore autonomo, è necessaria una DLL lato debug.

Nel codice sul lato debug:

  • Per consentire al visualizzatore di modificare gli oggetti dati, l'origine oggetto deve ereditare da VisualizerObjectSource ed eseguire l'override dei TransferData metodi o CreateReplacementObject .

  • Se è necessario supportare il multitargeting nel visualizzatore, è possibile usare i seguenti moniker (TFM) del framework di destinazione nel file di progetto sul lato debug.

    <TargetFrameworks>net20;netstandard2.0;netcoreapp2.0</TargetFrameworks>
    

    Questi sono gli unici TFM supportati.

Considerazioni speciali sul lato debug per .NET 5.0+

Importante

Potrebbero essere necessari passaggi aggiuntivi per il funzionamento di un visualizzatore a partire da .NET 5.0 a causa di problemi di sicurezza relativi al metodo di serializzazione binario sottostante usato per impostazione predefinita. Leggere questa sezione prima di continuare.

  • Se il visualizzatore implementa il TransferData metodo , usare il metodo appena aggiunto GetDeserializableObject disponibile nella versione più recente di VisualizerObjectSource. Restituisce IDeserializableObject consente di determinare il formato di serializzazione dell'oggetto (binario o JSON) e di deserializzare l'oggetto sottostante in modo che possa essere usato.

  • Se il lato debug restituisce dati sul lato debugger come parte della TransferData chiamata, serializzare la risposta al flusso sul lato debugger tramite il Serialize metodo .