web-dev-qa-db-fra.com

avec Azure brokeredmessage obtenir le corps sans connaître le type

Lorsque vous utilisez le message négocié dans Azure Service Bus, vous pouvez récupérer le corps du message avec l'appel .GetBody. Le code est simple:

var msg = subscription.Receive();
MyPayload payload = msg.GetBody<MyPayload>();

Cependant, existe-t-il un moyen de récupérer le corps sans connaître explicitement la classe de l'objet corps?

var msg = subscription.Receive();
Type bodyType = Type.GetType( msg.ContentType);

var payload = msg.GetBody<bodyType>();
32
yamspog

Voici le code complet à désérialiser du message brokeré:

public T GetBody<T>(BrokeredMessage brokeredMessage)
{
  var ct = brokeredMessage.ContentType;
  Type bodyType = Type.GetType(ct, true);

  var stream = brokeredMessage.GetBody<Stream>();
  DataContractSerializer serializer = new DataContractSerializer(bodyType);
  XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max);
  object deserializedBody = serializer.ReadObject(reader);
  T msgBase = (T)deserializedBody;
  return msgBase;
}
32
yamspog

Si l'intention est de saisir uniquement le corps du message quel que soit le contenu, vous pouvez l'obtenir sous forme de flux.

Stream stream = message.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string s = reader.ReadToEnd();
70
ckross01

Dans l'échantillon avant ContentType utilisé pour détecter le type de corps. Je pense que ContentType doit être défini par l'expéditeur. Je fais une logique similaire, je définis l'une des propriétés du message sur le type d'objet du côté expéditeur et j'appelle GetBody <> () sur le récepteur avec le type récupéré de la propriété du message. comme ça:

public void SendData(object payloadData)
    {
        if (payloadData == null) return;

        var queueClient = QueueClient.CreateFromConnectionString(ConnectionString, _queueName);

        var brokeredMessage = new BrokeredMessage(payloadData);
        brokeredMessage.Properties["messageType"] = payloadData.GetType().AssemblyQualifiedName;
        queueClient.Send(brokeredMessage);
    }

La propriété de message "messageType" a le nom complet de type.

Côté réception, j'aime ça:

 var messageBodyType = Type.GetType(receivedMessage.Properties["messageType"].ToString());
                if (messageBodyType == null)
                {
                    //Should never get here as a messagebodytype should
                    //always be set BEFORE putting the message on the queue
                    Trace.TraceError("Message does not have a messagebodytype" +
                                     " specified, message {0}", receivedMessage.MessageId);
                    receivedMessage.DeadLetter();
                }


                //read body only if event handler hooked
                    var method = typeof(BrokeredMessage).GetMethod("GetBody", new Type[] { });
                    var generic = method.MakeGenericMethod(messageBodyType);
                    try
                    {
                        var messageBody = generic.Invoke(receivedMessage, null);
                         DoSomethingWithYourData();
                        receivedMessage.Complete();
                    }
                    catch (Exception e)
                    {
                        Debug.Write("Can not handle message. Abandoning.");
                        receivedMessage.Abandon();
                    }
                }
5
Vitaliy Markitanov