Exception.Data Właściwość

Definicja

Pobiera kolekcję par klucz/wartość, które zapewniają dodatkowe informacje zdefiniowane przez użytkownika dotyczące wyjątku.

public:
 virtual property System::Collections::IDictionary ^ Data { System::Collections::IDictionary ^ get(); };
public virtual System.Collections.IDictionary Data { get; }
member this.Data : System.Collections.IDictionary
Public Overridable ReadOnly Property Data As IDictionary

Wartość właściwości

IDictionary

Obiekt, który implementuje IDictionary interfejs i zawiera kolekcję par klucz/wartość zdefiniowanych przez użytkownika. Wartością domyślną jest pusta kolekcja.

Przykłady

W poniższym przykładzie pokazano, jak dodawać i pobierać informacje przy użyciu Data właściwości .

using namespace System;
using namespace System::Collections;

void NestedRunTest( bool displayDetails ); // forward declarations
void NestedRoutine1( bool displayDetails );
void NestedRoutine2( bool displayDetails );
void RunTest( bool displayDetails );

int main()
{
   Console::WriteLine("\nException with some extra information..." );
   RunTest(false);
   Console::WriteLine("\nException with all extra information..." );
   RunTest(true);
}

void RunTest( bool displayDetails )
{
   try
   {
      NestedRoutine1( displayDetails );
   }
   catch ( Exception^ e ) 
   {
      Console::WriteLine( "An exception was thrown." );
      Console::WriteLine( e->Message );
      if ( e->Data != nullptr )
      {
         Console::WriteLine( "  Extra details:" );

         for each (DictionaryEntry de in e->Data)
            Console::WriteLine("    Key: {0,-20}      Value: {1}", 
                               "'" + de.Key->ToString() + "'", de.Value);
      }
   }
}

void NestedRoutine1( bool displayDetails )
{
   try
   {
      NestedRoutine2( displayDetails );
   }
   catch ( Exception^ e ) 
   {
      e->Data[ "ExtraInfo" ] = "Information from NestedRoutine1.";
      e->Data->Add( "MoreExtraInfo", "More information from NestedRoutine1." );
      throw;
   }
}

void NestedRoutine2( bool displayDetails )
{
   Exception^ e = gcnew Exception( "This statement is the original exception message." );
   if ( displayDetails )
   {
      String^ s = "Information from NestedRoutine2.";
      int i = -903;
      DateTime dt = DateTime::Now;
      e->Data->Add( "stringInfo", s );
      e->Data[ "IntInfo" ] = i;
      e->Data[ "DateTimeInfo" ] = dt;
   }

   throw e;
}

/*
This example produces the following results:

Exception with some extra information...
An exception was thrown.
This statement is the original exception message.
  Extra details:
    The key is 'ExtraInfo' and the value is: Information from NestedRoutine1.
    The key is 'MoreExtraInfo' and the value is: More information from NestedRoutine1.

Exception with all extra information...
An exception was thrown.
This statement is the original exception message.
  Extra details:
    The key is 'stringInfo' and the value is: Information from NestedRoutine2.
    The key is 'IntInfo' and the value is: -903
    The key is 'DateTimeInfo' and the value is: 11/26/2002 2:12:58 PM
    The key is 'ExtraInfo' and the value is: Information from NestedRoutine1.
    The key is 'MoreExtraInfo' and the value is: More information from NestedRoutine1.
*/
// This example demonstrates the Exception.Data property.
using System;
using System.Collections;

class Sample
{
   public static void Main()
   {
      Console.WriteLine("\nException with some extra information...");
      RunTest(false);
      Console.WriteLine("\nException with all extra information...");
      RunTest(true);
   }

   public static void RunTest(bool displayDetails)
   {
      try {
         NestedRoutine1(displayDetails);
      }
      catch (Exception e) {
         Console.WriteLine("An exception was thrown.");
         Console.WriteLine(e.Message);
         if (e.Data.Count > 0) {
            Console.WriteLine("  Extra details:");
            foreach (DictionaryEntry de in e.Data)
               Console.WriteLine("    Key: {0,-20}      Value: {1}",
                                 "'" + de.Key.ToString() + "'", de.Value);
         }
      }
   }

   public static void NestedRoutine1(bool displayDetails)
   {
      try {
         NestedRoutine2(displayDetails);
      }
      catch (Exception e) {
         e.Data["ExtraInfo"] = "Information from NestedRoutine1.";
         e.Data.Add("MoreExtraInfo", "More information from NestedRoutine1.");
         throw;
      }
   }

   public static void NestedRoutine2(bool displayDetails)
   {
      Exception e = new Exception("This statement is the original exception message.");
      if (displayDetails) {
         string s = "Information from NestedRoutine2.";
         int i = -903;
         DateTime dt = DateTime.Now;
         e.Data.Add("stringInfo", s);
         e.Data["IntInfo"] = i;
         e.Data["DateTimeInfo"] = dt;
      }
      throw e;
   }
}
// The example displays the following output:
//    Exception with some extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
//
//    Exception with all extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'stringInfo'              Value: Information from NestedRoutine2.
//        Key: 'IntInfo'                 Value: -903
//        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
// This example demonstrates the Exception.Data property.
open System
open System.Collections

let nestedRoutine2 displayDetails =
    let e = Exception "This statement is the original exception message."
    if displayDetails then
        let s = "Information from nestedRoutine2."
        let i = -903
        let dt = DateTime.Now
        e.Data.Add("stringInfo", s)
        e.Data["IntInfo"] <- i
        e.Data["DateTimeInfo"] <- dt
    raise e

let nestedRoutine1 displayDetails =
    try
        nestedRoutine2 displayDetails
    with e ->
        e.Data["ExtraInfo"] <- "Information from nestedRoutine1."
        e.Data.Add("MoreExtraInfo", "More information from nestedRoutine1.")
        reraise ()

let runTest displayDetails =
    try
        nestedRoutine1 displayDetails
    with e ->
        printfn "An exception was thrown."
        printfn $"{e.Message}"
        if e.Data.Count > 0 then
            printfn "  Extra details:"
            for de in e.Data do
                let de = de :?> DictionaryEntry
                printfn $"""    Key: {"'" + de.Key.ToString() + "'",-20}      Value: {de.Value}"""

printfn "\nException with some extra information..."
runTest false
printfn "\nException with all extra information..."
runTest true

   
// The example displays the following output:
//    Exception with some extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
//
//    Exception with all extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'stringInfo'              Value: Information from NestedRoutine2.
//        Key: 'IntInfo'                 Value: -903
//        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
Imports System.Collections

Module Example
   Public Sub Main()
      Console.WriteLine()
      Console.WriteLine("Exception with some extra information...")
      RunTest(False)
      Console.WriteLine()
      Console.WriteLine("Exception with all extra information...")
      RunTest(True)
   End Sub

   Public Sub RunTest(displayDetails As Boolean)
      Try
         NestedRoutine1(displayDetails)
      Catch e As Exception
         Console.WriteLine("An exception was thrown.")
         Console.WriteLine(e.Message)
         If e.Data.Count > 0 Then
            Console.WriteLine("  Extra details:")
            For Each de As DictionaryEntry In e.Data
               Console.WriteLine("    Key: {0,-20}      Value: {1}",
                                 "'" + de.Key.ToString() + "'", de.Value)
            Next
         End If 
      End Try 
   End Sub 

   Public Sub NestedRoutine1(displayDetails As Boolean)
      Try
         NestedRoutine2(displayDetails)
      Catch e As Exception
         e.Data("ExtraInfo") = "Information from NestedRoutine1."
         e.Data.Add("MoreExtraInfo", "More information from NestedRoutine1.")
         Throw e
      End Try 
   End Sub

   Public Sub NestedRoutine2(displayDetails As Boolean)
      Dim e As New Exception("This statement is the original exception message.")
      If displayDetails Then 
         Dim s As String = "Information from NestedRoutine2." 
         Dim i As Integer = -903
         Dim dt As DateTime = DateTime.Now
         e.Data.Add("stringInfo", s)
         e.Data("IntInfo") = i
         e.Data("DateTimeInfo") = dt
      End If 
      Throw e
   End Sub 
End Module
' This example displays the following output: 
'    Exception with some extra information...
'    An exception was thrown.
'    This statement is the original exception message.
'      Extra details:
'        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
'        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
'    
'    Exception with all extra information...
'    An exception was thrown.
'    This statement is the original exception message.
'      Extra details:
'        Key: 'stringInfo'              Value: Information from NestedRoutine2.
'        Key: 'IntInfo'                 Value: -903
'        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
'        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
'        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.

Uwagi

System.Collections.IDictionary Użyj obiektu zwróconego Data przez właściwość, aby przechowywać i pobierać dodatkowe informacje istotne dla wyjątku. Informacje są w postaci dowolnej liczby par klucz/wartość zdefiniowanych przez użytkownika. Kluczowym składnikiem każdej pary klucz/wartość jest zazwyczaj ciąg identyfikujący, podczas gdy składnik wartości pary może być dowolnym typem obiektu.

Zabezpieczenia pary klucz/wartość

Pary klucz/wartość przechowywane w kolekcji zwracanej przez Data właściwość nie są bezpieczne. Jeśli aplikacja wywołuje zagnieżdżonych serii procedur, a każda procedura zawiera procedury obsługi wyjątków, wynikowy stos wywołań zawiera hierarchię tych procedur obsługi wyjątków. Jeśli procedura niższego poziomu zgłasza wyjątek, każdy program obsługi wyjątków wyższego poziomu w hierarchii stosu wywołań może odczytywać i/lub modyfikować pary klucz/wartość przechowywane w kolekcji przez dowolną inną procedurę obsługi wyjątków. Oznacza to, że należy zagwarantować, że informacje w parach klucz/wartość nie są poufne i że aplikacja będzie działać poprawnie, jeśli informacje w parach klucz/wartość są uszkodzone.

Konflikty klucza

Konflikt klucza występuje, gdy różne programy obsługi wyjątków określają ten sam klucz, aby uzyskać dostęp do pary klucz/wartość. Należy zachować ostrożność podczas tworzenia aplikacji, ponieważ konsekwencją konfliktu klucza jest to, że programy obsługi wyjątków niższego poziomu mogą przypadkowo komunikować się z procedurami obsługi wyjątków wyższego poziomu, a ta komunikacja może powodować drobne błędy programu. Jeśli jednak zachowasz ostrożność, możesz użyć konfliktów kluczy, aby ulepszyć aplikację.

Unikanie konfliktów klucza

Unikaj konfliktów kluczy, stosując konwencję nazewnictwa w celu generowania unikatowych kluczy dla par klucz/wartość. Na przykład konwencja nazewnictwa może spowodować uzyskanie klucza składającego się z nazwy aplikacji rozdzielanej kropkami, metody, która udostępnia dodatkowe informacje dla pary i unikatowy identyfikator.

Załóżmy, że dwie aplikacje o nazwie Products (Produkty) i Suppliers (Dostawcy) mają metodę o nazwie Sales (Sprzedaż). Metoda Sales w aplikacji Products udostępnia numer identyfikacyjny (jednostkę magazynową lub jednostkę SKU) produktu. Metoda Sales w aplikacji Suppliers udostępnia numer identyfikacyjny lub identyfikator SID dostawcy. W związku z tym konwencja nazewnictwa dla tego przykładu daje klucze "Products.Sales.SKU" i "Suppliers.Sales.SID".

Wykorzystanie konfliktów klucza

Konflikty kluczy wykorzystujących luki w zabezpieczeniach przy użyciu co najmniej jednego specjalnego, wstępnie ułożonego klucza do kontrolowania przetwarzania. Załóżmy, że w jednym scenariuszu procedura obsługi wyjątków najwyższego poziomu w hierarchii stosu wywołań przechwytuje wszystkie wyjątki zgłaszane przez programy obsługi wyjątków niższego poziomu. Jeśli istnieje para klucz/wartość ze specjalnym kluczem, procedura obsługi wyjątków wysokiego poziomu formatuje pozostałe pary klucz/wartość w IDictionary obiekcie w sposób niestandardowy; w przeciwnym razie pozostałe pary klucz/wartość są formatowane w normalny sposób.

Załóżmy, że w innym scenariuszu program obsługi wyjątków na każdym poziomie hierarchii stosu wywołań przechwytuje wyjątek zgłoszony przez następną procedurę obsługi wyjątków niższego poziomu. Ponadto każda procedura obsługi wyjątków wie, że kolekcja zwrócona przez Data właściwość zawiera zestaw par klucz/wartość, do których można uzyskać dostęp za pomocą wstępnie ustawionego zestawu kluczy.

Każda procedura obsługi wyjątków używa wstępnie ułożonego zestawu kluczy, aby zaktualizować składnik wartości odpowiedniej pary klucz/wartość z informacjami unikatowymi dla tej procedury obsługi wyjątków. Po zakończeniu procesu aktualizacji program obsługi wyjątków zgłasza wyjątek do następnej procedury obsługi wyjątków wyższego poziomu. Na koniec procedura obsługi wyjątków najwyższego poziomu uzyskuje dostęp do par klucz/wartość i wyświetla skonsolidowane informacje o aktualizacji ze wszystkich procedur obsługi wyjątków niższego poziomu.

Dotyczy

Zobacz też