Lectura, escritura y copia de un mensaje en WCF I

La vida es como una sucesión de círculos que se repiten. Hace más de un año y medio, desarrollando nuestra primera aplicación con WCF se nos planteó el problema del que hablo a continuación. Hace unos días, a otro equipo de mi empresa le sucedió lo mismo. Debido a esto, he pensado que estaría bien comentarlo de nuevo.
Comentaros que no he vuelto a revisar las clases implicadas desde entonces, por si actualmente hay alguna otra solución al tema, por lo que se agradece cualquier sugerencia-puntualización que podáis darme.
En este post, plantearé el problema, para en los siguientes, explicar la manera como lo solucionamos en su momento.
Un mensaje de WCF es de un solo uso. ¿Qué quiere decir esto? Que sólo se puede acceder para realizar alguna acción sobre el mismo, ya sea de lectura, escritura o copia, cuando está creado y no se ha realizado anteriormente alguna de estas acciones sobre él.
Si por ejemplo, en algún proceso se intenta obtener el “Body” del mensaje, esto implicará una lectura del mismo, por lo que cualquier otro intento de lectura producirá el error: System.InvalidOperationException, indicándonos que el mensaje ya ha sido leído, Esto sucederá incluso en el caso de que se produzca algún tipo de error durante la lectura como podría ser un error de conversión en el tipo recibido durante el acceso al cuerpo del mensaje, porque como veremos más adelante, lo primero que hace ante una operación sobre el mensaje es comprobar su estado actual y si este es correcto o mejor dicho, adecuado, el siguiente paso es cambiarle al estado que corresponda.

Pueden producir este error varias acciones que llevemos a cabo en el mensaje, por ejemplo:
Dos llamadas consecutivas al método del mensaje, GetBody. volver a pasar el mensaje por la pila de canales para su reenvío a otro servicio mediante un cliente Proxy, si después de acceder al mensaje con GetBody, lo pasamos como parámetro en algún método del servicio; las posibilidades son muchas, en cualquier caso, el hecho común es intentar acceder al mensaje más de una vez.

El motivo de esta implementación del objeto Message, es que pueda admitir stream, por lo que de esta manera se garantiza que sólo se procese una vez.

La propiedad a a través de la cual WCF controla esta situación es State, la cual puede tomar los siguientes valores. Creado, Leido, Escrito, Copiado, y cerrado, que determinará que operaciones se pueden o no se pueden realizar con el mensaje.
La enumeración que nos proporciona los valores de esta propiedad es la siguiente:
Se encuentra en System.ServiceModel.Channels

Public enum MessageState
{
Created,
Read,
Writen,
Copied,
Closed
}
Obviamente la propiedad State hace que sea posible determinar en tiempo de ejecución si el cuerpo de un Message particular ya se ha consumido (cuando ya no está en estado Created) y cómo se consumió (si se leyó, escribió o copió).

Esta propiedad hace posible que en cualquier momento de la ejecución de nuestra aplicación, podamos saber si el mensaje ya ha sido tratado y que se hizo con el mismo, es decir, si se copió, escribió, etc.El único estado correcto que nos permitirá acceder al cuerpo del mensaje, ya sea para leer, escribir o copiar, será el estado Created.

2 comentarios sobre “Lectura, escritura y copia de un mensaje en WCF I”

  1. algún ejemplo de código estaría bien…gracias

    y qué pasa con el tema de diagnostics, logging de los mensajes ?? es decir, se pueden trazar los mensajes WCF, no? y luego el propio programador puede acceder al Body por ejemplo…

    salu2grz

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *