Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las excepciones se usan para comunicar errores localmente dentro del servicio o la implementación del cliente. Por otro lado, los errores se usan para comunicar errores a través de los límites del servicio, como desde el servidor al cliente o viceversa. Además de los errores, los canales de transporte suelen usar mecanismos específicos del transporte para comunicar errores de nivel de transporte. Por ejemplo, el transporte HTTP usa códigos de estado como 404 para comunicar una dirección URL de punto de conexión no existente (no hay ningún punto de conexión para devolver un error). Este documento consta de tres secciones que proporcionan instrucciones para los autores de canales personalizados. En la primera sección se proporcionan instrucciones sobre cuándo y cómo definir e iniciar excepciones. La segunda sección proporciona una guía sobre la generación y utilización de errores. En la tercera sección se explica cómo proporcionar información de seguimiento para ayudar al usuario del canal personalizado a solucionar problemas de aplicaciones en ejecución.
Excepciones
Hay dos cosas que hay que tener en cuenta al iniciar una excepción: primero debe ser de un tipo que permita a los usuarios escribir código correcto que pueda reaccionar adecuadamente a la excepción. En segundo lugar, tiene que proporcionar suficiente información para que el usuario comprenda lo que ha ido mal, el impacto del error y cómo corregirlo. En las secciones siguientes se proporcionan instrucciones sobre los tipos de excepción y los mensajes para los canales de Windows Communication Foundation (WCF). También hay instrucciones generales sobre excepciones en .NET en el documento Directrices de diseño para excepciones.
Tipos de excepción
Todas las excepciones producidas por canales deben ser System.TimeoutException, System.ServiceModel.CommunicationException o un tipo derivado de CommunicationException. (También se pueden producir excepciones como ObjectDisposedException , pero solo para indicar que el código que realiza la llamada ha mal usado el canal. Si un canal se usa correctamente, solo debe iniciar las excepciones especificadas). WCF proporciona siete tipos de excepción que derivan de CommunicationException y están diseñados para que los canales los usen. Hay otras CommunicationExceptionexcepciones derivadas diseñadas para ser utilizadas por otras partes del sistema. Estos tipos de excepción son:
Tipo de excepción | Significado | Contenido de excepción interna | Estrategia de recuperación |
---|---|---|---|
AddressAlreadyInUseException | La dirección del punto de conexión especificada para escuchar ya está en uso. | Si está presente, proporciona más detalles sobre el error de transporte que provocó esta excepción. Por ejemplo. PipeException, HttpListenerException, o SocketException. | Pruebe una dirección diferente. |
AddressAccessDeniedException | No se permite al proceso acceder a la dirección del punto de conexión especificada para la escucha. | Si está presente, proporciona más detalles sobre el error de transporte que provocó esta excepción. Por ejemplo, PipeException o HttpListenerException. | Pruebe con credenciales diferentes. |
CommunicationObjectFaultedException | El ICommunicationObject que se usa está en estado Defectuoso (para obtener más información, vea Descripción de los cambios de estado). Tenga en cuenta que cuando un objeto con varias llamadas pendientes pasa al estado Faulted, solo una llamada produce una excepción relacionada con el error y el resto de las llamadas inician un CommunicationObjectFaultedException. Normalmente, esta excepción se produce porque una aplicación pasa por alto alguna excepción e intenta usar un objeto ya con errores, posiblemente en un subproceso distinto del que detectó la excepción original. | Si está presente, proporciona detalles sobre la excepción interna. | Cree un nuevo objeto. Tenga en cuenta que, dependiendo de lo que causó que el ICommunicationObject fallara inicialmente, puede ser necesario realizar otros trabajos para recuperar. |
CommunicationObjectAbortedException | Se ha anulado el elemento ICommunicationObject que se usa (para obtener más información, vea Descripción de los cambios de estado). De forma similar a CommunicationObjectFaultedException, esta excepción indica que la aplicación ha llamado Abort en el objeto, posiblemente desde otro subproceso, y el objeto ya no se puede usar por ese motivo. | Si está presente, proporciona detalles sobre la excepción interna. | Cree un nuevo objeto. Tenga en cuenta que dependiendo de lo que provocó la anulación de ICommunicationObject en primer lugar, puede haber otro trabajo implicado para recuperarlo. |
EndpointNotFoundException | El punto de conexión remoto de destino no está escuchando. Esto puede deberse a que cualquier parte de la dirección del punto de conexión es incorrecta, irresolvable o el punto de conexión está inactivo. Entre los ejemplos se incluyen el error DE DNS, el Administrador de colas no está disponible y el servicio no se está ejecutando. | La excepción interna proporciona detalles, normalmente del transporte subyacente. | Pruebe una dirección diferente. Como alternativa, el remitente puede esperar un rato e intentarlo de nuevo en caso de que el servicio esté inactivo. |
ProtocolException | Los protocolos de comunicación, tal como se describe en la directiva del punto de conexión, no coinciden entre los puntos de conexión. Por ejemplo, desajuste de tipo de contenido de encuadre o tamaño máximo del mensaje excedido. | Si está presente proporciona más información sobre el error de protocolo específico. Por ejemplo, QuotaExceededException es la excepción interna cuando la causa del error supera MaxReceivedMessageSize. | Recuperación: asegúrese de que la configuración del remitente y del protocolo recibido coincida. Una manera de hacerlo es volver a importar los metadatos (directiva) del punto de conexión de servicio y usar el enlace generado para volver a crear el canal. |
ServerTooBusyException | El punto de conexión remoto está escuchando, pero no está preparado para procesar mensajes. | Si está presente, la excepción interna proporciona los detalles de error de SOAP o de nivel de transporte. | Recuperación: espere y vuelva a intentar la operación más adelante. |
TimeoutException | No se pudo completar la operación en el período de tiempo de espera. | Puede proporcionar los detalles sobre el tiempo de espera. | Espere y vuelva a intentar la operación más adelante. |
Defina un nuevo tipo de excepción solo si ese tipo corresponde a una estrategia de recuperación específica diferente de todos los tipos de excepción existentes. Si define un nuevo tipo de excepción, debe derivar de CommunicationException o de una de sus clases derivadas.
Mensajes de excepción
Los mensajes de excepción están dirigidos al usuario no al programa, por lo que deben proporcionar información suficiente para ayudar al usuario a comprender y resolver el problema. Las tres partes esenciales de un buen mensaje de excepción son:
¿Qué pasó. Proporcione una descripción clara del problema mediante términos relacionados con la experiencia del usuario. Por ejemplo, un mensaje de excepción incorrecto sería "Sección de configuración no válida". Esto deja al usuario preguntándose qué sección de configuración es incorrecta y por qué es incorrecto. Un mensaje mejorado sería "Sección de configuración <no válida customBinding>". Un mensaje aún mejor sería "No se puede agregar el transporte denominado myTransport al enlace denominado myBinding porque el enlace ya tiene un transporte denominado myTransport". Se trata de un mensaje muy específico mediante términos y nombres que el usuario puede identificar fácilmente en el archivo de configuración de la aplicación. Sin embargo, todavía faltan algunos componentes clave.
Importancia del error. A menos que el mensaje indique claramente lo que significa el error, es probable que el usuario se pregunte si es un error irrecuperable o si se puede omitir. En general, los mensajes deben comenzar con el significado o la importancia del error. Para mejorar el ejemplo anterior, el mensaje podría ser "ServiceHost no se pudo abrir debido a un error de configuración: No se puede agregar el transporte denominado myTransport al enlace denominado myBinding porque el enlace ya tiene un transporte denominado myTransport".
Cómo debe corregir el problema el usuario. La parte más importante del mensaje es ayudar al usuario a solucionar el problema. El mensaje debe incluir algunas instrucciones o sugerencias sobre qué comprobar o corregir para solucionar el problema. Por ejemplo, "ServiceHost no pudo abrir debido a un error de configuración: no se puede agregar el transporte denominado myTransport al enlace denominado myBinding porque el enlace ya tiene un transporte denominado myTransport. Asegúrese de que solo haya un transporte en el enlace."
Comunicación de errores
SOAP 1.1 y SOAP 1.2 definen una estructura específica para errores. Hay algunas diferencias entre las dos especificaciones pero en general, los tipos Message y MessageFault se utilizan para crear y utilizar los errores.
Fallo SOAP 1.2 (izquierda) y fallo SOAP 1.1 (derecha). En SOAP 1.1 solo el elemento Fault está calificado con el espacio de nombres.
SOAP define un mensaje de error como un mensaje que contiene solo un elemento de error (un elemento cuyo nombre es <env:Fault>
) como elemento secundario de <env:Body>
. El contenido del elemento de error difiere ligeramente entre SOAP 1.1 y SOAP 1.2, como se muestra en la figura 1. Sin embargo, la System.ServiceModel.Channels.MessageFault clase normaliza estas diferencias en un modelo de objetos:
public abstract class MessageFault
{
protected MessageFault();
public virtual string Actor { get; }
public virtual string Node { get; }
public static string DefaultAction { get; }
public abstract FaultCode Code { get; }
public abstract bool HasDetail { get; }
public abstract FaultReason Reason { get; }
public T GetDetail<T>();
public T GetDetail<T>( XmlObjectSerializer serializer);
public System.Xml.XmlDictionaryReader GetReaderAtDetailContents();
// other methods omitted
}
La Code
propiedad corresponde a env:Code
(o faultCode
en SOAP 1.1) e identifica el tipo del error. SOAP 1.2 define cinco valores permitidos para faultCode
(por ejemplo, Remitente y Receptor) y define un Subcode
elemento que puede contener cualquier valor de subcódigo. (Vea la especificación SOAP 1.2 para obtener la lista de códigos de error permitidos y su significado). SOAP 1.1 tiene un mecanismo ligeramente diferente: define cuatro faultCode
valores (por ejemplo, Cliente y Servidor) que se pueden extender definiendo completamente nuevos o usando la notación de puntos para crear faultCodes
, por ejemplo, Client.Authentication.
Cuando se utiliza MessageFault para programar errores, FaultCode.Name y FaultCode.Namespace se asignan al nombre y al espacio de nombres de SOAP 1.2 env:Code
o SOAP 1.1 faultCode
. FaultCode.SubCode se mapea a env:Subcode
para SOAP 1.2 y es nulo para SOAP 1.1.
Debe crear nuevos subcódigos de error (o códigos de error nuevos si usa SOAP 1.1) si es interesante distinguir mediante programación un error. Esto es análogo a la creación de un nuevo tipo de excepción. Debería evitar utilizar la notación de puntos con códigos de error de SOAP 1.1. (En Perfil básico de WS-I también se desaconseja el uso de la notación de puntos en los códigos de error).
public class FaultCode
{
public FaultCode(string name);
public FaultCode(string name, FaultCode subCode);
public FaultCode(string name, string ns);
public FaultCode(string name, string ns, FaultCode subCode);
public bool IsPredefinedFault { get; }
public bool IsReceiverFault { get; }
public bool IsSenderFault { get; }
public string Name { get; }
public string Namespace { get; }
public FaultCode SubCode { get; }
// methods omitted
}
La propiedad Reason
corresponde a env:Reason
(o faultString
en SOAP 1.1), una descripción legible de la condición de error análoga al mensaje de una excepción. La FaultReason
clase (y SOAP env:Reason/faultString
) tiene soporte integrado para tener varias traducciones en aras de la globalización.
public class FaultReason
{
public FaultReason(FaultReasonText translation);
public FaultReason(IEnumerable<FaultReasonText> translations);
public FaultReason(string text);
public SynchronizedReadOnlyCollection<FaultReasonText> Translations
{
get;
}
}
El contenido de detalles del error se expone en MessageFault mediante varios métodos, como T GetDetail
<> y GetReaderAtDetailContents
(). El detalle del error es un elemento opaco para llevar el detalle adicional sobre el error. Esto es útil si es algún detalle estructurado arbitrario que desea llevar con el error.
Generar errores
En esta sección se explica el proceso de generar un error en respuesta a una condición de error detectada en un canal o en una propiedad de mensaje creada por el canal. Un ejemplo típico es devolver un error en respuesta a un mensaje de solicitud que contiene datos no válidos.
Al generar un error, el canal personalizado no debe enviar el error directamente, sino que debería producir una excepción y dejar que la capa anterior decida si desea convertir esa excepción en un error y cómo enviarla. Para ayudar en esta conversión, el canal debe proporcionar una FaultConverter
implementación que pueda convertir la excepción producida por el canal personalizado en el error adecuado.
FaultConverter
se define como:
public class FaultConverter
{
public static FaultConverter GetDefaultFaultConverter(
MessageVersion version);
protected abstract bool OnTryCreateFaultMessage(
Exception exception,
out Message message);
public bool TryCreateFaultMessage(
Exception exception,
out Message message);
}
Cada canal que genera errores personalizados debe implementar FaultConverter
y devolverlo de una llamada a GetProperty<FaultConverter>
. La implementación de OnTryCreateFaultMessage
personalizada debe convertir la excepción en un error o delegar al elemento FaultConverter
del canal interno. Si el canal es un transporte, debe convertir la excepción o delegar en FaultConverter
del codificador o en el elemento FaultConverter
predeterminado proporcionado en WCF. El valor predeterminado FaultConverter
convierte los errores correspondientes a los mensajes de error especificados por WS-Addressing y SOAP. Este es un ejemplo OnTryCreateFaultMessage
de implementación.
public override bool OnTryCreateFaultMessage(Exception exception,
out Message message)
{
if (exception is ...)
{
message = ...;
return true;
}
#if IMPLEMENTING_TRANSPORT_CHANNEL
FaultConverter encoderConverter =
this.encoder.GetProperty<FaultConverter>();
if ((encoderConverter != null) &&
(encoderConverter.TryCreateFaultMessage(
exception, out message)))
{
return true;
}
FaultConverter defaultConverter =
FaultConverter.GetDefaultFaultConverter(
this.channel.messageVersion);
return defaultConverter.TryCreateFaultMessage(
exception,
out message);
#else
FaultConverter inner =
this.innerChannel.GetProperty<FaultConverter>();
if (inner != null)
{
return inner.TryCreateFaultMessage(exception, out message);
}
else
{
message = null;
return false;
}
#endif
}
Una implicación de este patrón es que las excepciones lanzadas entre capas para las condiciones de error que requieren fallos deben contener suficiente información para que el generador de fallos correspondiente cree el fallo correcto. Como autor de canal personalizado, puede definir tipos de excepción que corresponden a condiciones de error diferentes si estas excepciones aún no existen. Observe que las excepciones que atraviesan las capas del canal deberían comunicar la condición de error en lugar de los datos del error opacos.
Categorías de errores
Por lo general, hay tres categorías de errores:
Errores que son generalizados en todo el stack. Estos errores se pueden encontrar en cualquier capa de la pila de canales, por ejemplo InvalidCardinalityAddressingException.
Errores que se pueden encontrar en cualquier lugar por encima de una determinada capa de la pila, por ejemplo, algunos errores que pertenecen a una transacción procesada o a roles relacionados con la seguridad.
Errores dirigidos a una capa única en la pila, por ejemplo, errores como los errores de número de secuencia de WS-RM.
Categoría 1. Los errores son generalmente errores de WS-Addressing y de SOAP. La clase base FaultConverter
proporcionada por WCF convierte los errores correspondientes a los mensajes de error especificados por WS-Addressing y SOAP, por lo que no es necesario controlar la conversión de estas excepciones usted mismo.
Categoría 2. Los errores se producen cuando una capa agrega una propiedad al mensaje que no consume completamente la información del mensaje que pertenece a esa capa. Los errores se pueden detectar más adelante cuando una capa superior pide a la propiedad message que procese más información del mensaje. Estos canales deben implementar el GetProperty
especificado anteriormente para permitir que la capa superior devuelva el error correcto. Un ejemplo de esto es TransactionMessageProperty. Esta propiedad se agrega al mensaje sin validar completamente todos los datos del encabezado (si lo hace, puede implicar ponerse en contacto con el coordinador de transacciones distribuidas (DTC).
Categoría 3. Los errores solo se generan y envían mediante una sola capa en el procesador. Por lo tanto, todas las excepciones están contenidas en la capa. Para mejorar la coherencia entre los canales y facilitar el mantenimiento, el canal personalizado debe usar el patrón especificado anteriormente para generar mensajes de error incluso para errores internos.
Interpretación de errores recibidos
En esta sección se proporcionan instrucciones para generar la excepción adecuada al recibir un mensaje de error. El árbol de decisión para procesar un mensaje en cada capa de la pila es el siguiente:
Si la capa considera que el mensaje no es válido, la capa debe realizar su procesamiento de "mensaje no válido". Este procesamiento es específico de la capa, pero podría incluir descartar el mensaje, rastrear o lanzar una excepción que se convierte en un fallo. Algunos ejemplos incluyen que el equipo de seguridad recibe un mensaje que no está protegido correctamente, o que RM recibe un mensaje con un número de secuencia incorrecto.
De lo contrario, si el mensaje es un mensaje de error que se aplica específicamente a la capa y el mensaje no es significativo fuera de la interacción de la capa, la capa debe controlar la condición de error. Un ejemplo de esto es un error de secuencia de RM rechazada que no tiene sentido para las capas sobre el canal RM y que implica un error en el canal RM y el inicio de las operaciones pendientes.
De lo contrario, el mensaje debe devolverse desde Request() o Receive(). Esto incluye los casos donde la capa reconoce el error, pero el error apenas indica que hubo un error en una solicitud y no implica un error en el canal y el inicio de las operaciones pendientes. Para mejorar la facilidad de uso en este caso, la capa debe implementar
GetProperty<FaultConverter>
y devolver unaFaultConverter
clase derivada que pueda convertir el error en una excepción invalidandoOnTryCreateException
.
El siguiente modelo de objetos admite la conversión de mensajes a excepciones:
public class FaultConverter
{
public static FaultConverter GetDefaultFaultConverter(
MessageVersion version);
protected abstract bool OnTryCreateException(
Message message,
MessageFault fault,
out Exception exception);
public bool TryCreateException(
Message message,
MessageFault fault,
out Exception exception);
}
Una capa de canal puede implementar GetProperty<FaultConverter>
para admitir la conversión de mensajes de error en excepciones. Para hacerlo, invalide OnTryCreateException
e inspeccione el mensaje de error. Si se reconoce, haga la conversión, de lo contrario pida al canal interno que lo convierta. Los canales de transporte deberían delegar a FaultConverter.GetDefaultFaultConverter
para obtener el SOAP predeterminado/FaultConverter de WS-Addressing.
Una implementación típica tiene este aspecto:
public override bool OnTryCreateException(
Message message,
MessageFault fault,
out Exception exception)
{
if (message.Action == "...")
{
exception = ...;
return true;
}
// OR
if ((fault.Code.Name == "...") && (fault.Code.Namespace == "..."))
{
exception = ...;
return true;
}
if (fault.IsMustUnderstand)
{
if (fault.WasHeaderNotUnderstood(
message.Headers, "...", "..."))
{
exception = new ProtocolException(...);
return true;
}
}
#if IMPLEMENTING_TRANSPORT_CHANNEL
FaultConverter encoderConverter =
this.encoder.GetProperty<FaultConverter>();
if ((encoderConverter != null) &&
(encoderConverter.TryCreateException(
message, fault, out exception)))
{
return true;
}
FaultConverter defaultConverter =
FaultConverter.GetDefaultFaultConverter(
this.channel.messageVersion);
return defaultConverter.TryCreateException(
message, fault, out exception);
#else
FaultConverter inner =
this.innerChannel.GetProperty<FaultConverter>();
if (inner != null)
{
return inner.TryCreateException(message, fault, out exception);
}
else
{
exception = null;
return false;
}
#endif
}
Para condiciones de error específicas que tienen distintos escenarios de recuperación, considere la posibilidad de definir una clase derivada de ProtocolException
.
Procesamiento de MustUnderstand
SOAP define un error general para indicar que el receptor no entendió un encabezado necesario. Este error se conoce como el mustUnderstand
error. En WCF, los canales personalizados nunca generan mustUnderstand
errores. En su lugar, el despachador de WCF, que se encuentra en la parte superior de la pila de comunicación de WCF, verifica que la pila subyacente haya entendido todos los encabezados marcados con MustUnderstand=true. Si alguno se entendió, se genera un error mustUnderstand
en ese punto. (El usuario puede optar por desactivar este mustUnderstand
procesamiento y hacer que la aplicación reciba todos los encabezados de mensaje. En ese caso, la aplicación es responsable de realizar el mustUnderstand
procesamiento). El error generado incluye un encabezado NotUnderstood que contiene los nombres de todos los encabezados con MustUnderstand=true que no se entendieron.
Si el canal de protocolo envía un encabezado personalizado con MustUnderstand=true y recibe un mustUnderstand
error, debe averiguar si ese error se debe al encabezado que envió. Hay dos miembros en la MessageFault
clase que son útiles para esto:
public class MessageFault
{
...
public bool IsMustUnderstandFault { get; }
public static bool WasHeaderNotUnderstood(MessageHeaders headers,
string name, string ns) { }
...
}
IsMustUnderstandFault
devuelve true
si el error es un mustUnderstand
error.
WasHeaderNotUnderstood
devuelve true
si el encabezado con el nombre y el espacio de nombres especificados está incluido en el error como un encabezado NotUnderstood. En caso contrario, devuelve false
.
Si un canal emite un encabezado marcado como MustUnderstand = true, esa capa también debe implementar el patrón de API de generación de excepciones y debe convertir mustUnderstand
los errores causados por ese encabezado en una excepción más útil, como se ha descrito anteriormente.
Rastreo
.NET Framework proporciona un mecanismo para realizar un seguimiento de la ejecución del programa como una manera de ayudar a diagnosticar aplicaciones de producción o problemas intermitentes en los que no es posible simplemente adjuntar un depurador y recorrer el código. Los componentes principales de este mecanismo están en el System.Diagnostics espacio de nombres y constan de:
System.Diagnostics.TraceSource, que es el origen de la información de seguimiento que se va a escribir, System.Diagnostics.TraceListener, que es una clase base abstracta para agentes de escucha concretos que reciben la información que se va a rastrear desde TraceSource y la envían a un destino específico del agente de escucha. Por ejemplo, XmlWriterTraceListener genera información de seguimiento en un archivo XML. Finalmente, System.Diagnostics.TraceSwitch, que permite al usuario de la aplicación controlar el nivel de detalle del seguimiento y normalmente se especifica en configuración.
Además de los componentes principales, puede usar la herramienta Herramienta de Visualización de Rastreos de Servicios (SvcTraceViewer.exe) para ver y buscar rastros de WCF. La herramienta está diseñada específicamente para archivos de seguimiento generados por WCF y escritos mediante XmlWriterTraceListener. En la ilustración siguiente se muestran los distintos componentes implicados en el seguimiento.
Seguimiento desde un canal personalizado
Los canales personalizados deben escribir mensajes de seguimiento para ayudar a diagnosticar problemas cuando no es posible adjuntar un depurador a la aplicación en ejecución. Esto implica dos tareas de alto nivel: crear una instancia de TraceSource y llamar a sus métodos para escribir las trazas.
Al crear una instancia de TraceSource, la cadena que especifique se convertirá en el nombre de esa fuente. Este nombre se usa para configurar (habilitar, deshabilitar o establecer el nivel de seguimiento) del origen de seguimiento. También aparece en el resultado del seguimiento. Los canales personalizados deben usar un nombre de origen único para ayudar a los lectores de la salida de seguimiento a comprender de dónde procede la información de seguimiento. El uso del nombre del ensamblado que escribe la información como nombre del origen de seguimiento es la práctica habitual. Por ejemplo, WCF usa System.ServiceModel como fuente de rastreo para información escrita desde el ensamblado System.ServiceModel.
Una vez tenga un origen de seguimiento, llame a sus métodos TraceData, TraceEvento TraceInformation para escribir las entradas de seguimiento en las escuchas de seguimiento. Para cada entrada de seguimiento que escriba, debe clasificar el tipo de evento como uno de los tipos de evento definidos en TraceEventType. Esta clasificación y la configuración del nivel de seguimiento determinan si la entrada de seguimiento se envía al agente de escucha. Por ejemplo, establecer el nivel de seguimiento en configuración en Warning
permite Warning
, Error
y que se escriban las entradas de seguimiento Critical
pero bloquea entradas de información y detalladas. A continuación un ejemplo para crear instancias de un origen de seguimiento y escribir una entrada en el nivel de información:
using System.Diagnostics;
//...
TraceSource udpSource = new TraceSource("Microsoft.Samples.Udp");
//...
udpsource.TraceInformation("UdpInputChannel received a message");
Importante
Se recomienda encarecidamente especificar un nombre de origen de seguimiento que sea único para el canal personalizado para ayudar a los lectores de salida de seguimiento a comprender de dónde procede la salida.
Integrar con el visor de seguimiento
Los seguimientos que genera el canal pueden generarse en un formato que pueda leer la Herramienta del visor de seguimiento de servicio (SvcTraceViewer.exe) mediante System.Diagnostics.XmlWriterTraceListener como cliente de escucha de seguimiento. Esto no es algo que usted, como desarrollador del canal, debe hacer. En su lugar, es el usuario de la aplicación (o la persona que soluciona problemas de la aplicación) quien necesita configurar este agente de escucha de seguimiento en el archivo de configuración de la aplicación. Por ejemplo, la siguiente configuración genera información de seguimiento de ambos System.ServiceModel y Microsoft.Samples.Udp
al archivo denominado TraceEventsFile.e2e
.
<configuration>
<system.diagnostics>
<sources>
<!-- configure System.ServiceModel trace source -->
<source name="System.ServiceModel" switchValue="Verbose"
propagateActivity="true">
<listeners>
<add name="e2e" />
</listeners>
</source>
<!-- configure Microsoft.Samples.Udp trace source -->
<source name="Microsoft.Samples.Udp" switchValue="Verbose" >
<listeners>
<add name="e2e" />
</listeners>
</source>
</sources>
<!--
Define a shared trace listener that outputs to TraceFile.e2e
The listener name is e2e
-->
<sharedListeners>
<add name="e2e" type="System.Diagnostics.XmlWriterTraceListener"
initializeData=".\TraceFile.e2e"/>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>
Seguimiento de datos estructurados
System.Diagnostics.TraceSource tiene un método TraceData que toma uno o más objetos que deben incluirse en la entrada de seguimiento. En general, se llama al Object.ToString método en cada objeto y la cadena resultante se escribe como parte de la entrada de seguimiento. Al usar System.Diagnostics.XmlWriterTraceListener para generar seguimientos, puede pasar un System.Xml.XPath.IXPathNavigable como objeto de datos a TraceData. La entrada de seguimiento resultante incluye el XML proporcionado por .System.Xml.XPath.XPathNavigator Esta es una entrada de ejemplo con datos de aplicación XML:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="...">
<EventID>12</EventID>
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2006-01-13T22:58:03.0654832Z" />
<Source Name="Microsoft.ServiceModel.Samples.Udp" />
<Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
<Execution ProcessName="UdpTestConsole"
ProcessID="3348" ThreadID="4" />
<Channel />
<Computer>COMPUTER-LT01</Computer>
</System>
<!-- XML application data -->
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord
Severity="Information"
xmlns="…">
<TraceIdentifier>some trace id</TraceIdentifier>
<Description>EndReceive called</Description>
<AppDomain>UdpTestConsole.exe</AppDomain>
<Source>UdpInputChannel</Source>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
El visor de seguimiento de WCF comprende el esquema del TraceRecord
elemento mostrado anteriormente y extrae los datos de sus elementos secundarios y los muestra en un formato tabular. Su canal debería utilizar este esquema al seguir paso a paso los datos de aplicación estructurados para ayudar a los usuarios de Svctraceviewer.exe a leer los datos.