Exception.Data Propiedad
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Obtiene una colección de pares clave/valor que proporciona información definida por el usuario adicional sobre la excepción.
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
Valor de propiedad
Objeto que implementa la interfaz de IDictionary y contiene una colección de pares clave-valor definidos por el usuario. El valor predeterminado es una colección vacía.
Ejemplos
En el ejemplo siguiente se muestra cómo agregar y recuperar información mediante la Data propiedad .
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.
Comentarios
Utilice el System.Collections.IDictionary objeto devuelto por la Data propiedad para almacenar y recuperar información complementaria relevante para la excepción. La información tiene la forma de un número arbitrario de pares clave-valor definidos por el usuario. El componente clave de cada par clave-valor suele ser una cadena de identificación, mientras que el componente de valor del par puede ser cualquier tipo de objeto.
Seguridad del par clave-valor
Los pares clave-valor almacenados en la colección devuelta por la Data propiedad no son seguros. Si la aplicación llama a una serie anidada de rutinas y cada rutina contiene controladores de excepciones, la pila de llamadas resultante contiene una jerarquía de esos controladores de excepciones. Si una rutina de nivel inferior produce una excepción, cualquier controlador de excepciones de nivel superior de la jerarquía de la pila de llamadas puede leer o modificar los pares clave-valor almacenados en la colección por cualquier otro controlador de excepciones. Esto significa que debe garantizar que la información de los pares clave-valor no es confidencial y que la aplicación funcionará correctamente si la información de los pares clave-valor está dañada.
Conflictos de claves
Se produce un conflicto de clave cuando distintos controladores de excepciones especifican la misma clave para tener acceso a un par clave-valor. Tenga cuidado al desarrollar la aplicación porque la consecuencia de un conflicto clave es que los controladores de excepciones de nivel inferior pueden comunicarse accidentalmente con controladores de excepciones de nivel superior y esta comunicación puede provocar errores de programa sutiles. Sin embargo, si tiene cuidado, puede usar conflictos clave para mejorar la aplicación.
Evitar conflictos clave
Evite conflictos de claves mediante la adopción de una convención de nomenclatura para generar claves únicas para pares clave-valor. Por ejemplo, una convención de nomenclatura podría producir una clave que consta del nombre delimitado por períodos de la aplicación, el método que proporciona información complementaria para el par y un identificador único.
Supongamos que dos aplicaciones, denominadas Products y Suppliers, cada una tiene un método denominado Sales. El método Sales de la aplicación Products proporciona el número de identificación (la unidad de mantenimiento de existencias o SKU) de un producto. El método Sales de la aplicación Proveedores proporciona el número de identificación, o SID, de un proveedor. Por lo tanto, la convención de nomenclatura de este ejemplo produce las claves, "Products.Sales.SKU" y "Suppliers.Sales.SID".
Vulnerabilidades de seguridad de conflictos de claves
Aproveche los conflictos de clave mediante la presencia de una o varias claves especiales y previamente ordenadas para controlar el procesamiento. Supongamos que, en un escenario, el controlador de excepciones de nivel más alto de la jerarquía de pila de llamadas detecta todas las excepciones producidas por controladores de excepciones de nivel inferior. Si existe un par clave-valor con una clave especial, el controlador de excepciones de alto nivel da formato a los pares clave-valor restantes del IDictionary objeto de alguna manera no estándar; de lo contrario, los pares clave-valor restantes tienen el formato normal.
Ahora supongamos que, en otro escenario, el controlador de excepciones en cada nivel de la jerarquía de pila de llamadas detecta la excepción producida por el siguiente controlador de excepciones de nivel inferior. Además, cada controlador de excepciones conoce la colección devuelta por la Data propiedad contiene un conjunto de pares clave-valor a los que se puede tener acceso con un conjunto de claves previamente ordenado.
Cada controlador de excepciones usa el conjunto predefinido de claves para actualizar el componente de valor del par clave-valor correspondiente con información única para ese controlador de excepciones. Una vez completado el proceso de actualización, el controlador de excepciones inicia la excepción en el siguiente controlador de excepciones de nivel superior. Por último, el controlador de excepciones de nivel más alto accede a los pares clave-valor y muestra la información de actualización consolidada de todos los controladores de excepciones de nivel inferior.