Utiliser Visual C# pour écrire et lire dans Microsoft Message Queuing

Cet article décrit la procédure d’écriture et de lecture de Microsoft Message Queuing (MSMQ) dans Visual C#.

Version du produit d’origine :   Mise en file d’attente de message Microsoft
Numéro de la base de connaissances initiale :   815811

Dans cette tâche

Résumé

Cet article rassemble les sections suivantes :

  • Comment créer un message et l’envoyer à MSMQ dans une application Windows.
  • Comment lire à partir d’une file d’attente privée et désérialiser le contenu du message pour l’affichage.

Configuration requise

Les éléments suivants décrivent le matériel, les logiciels, l’infrastructure réseau, les compétences et les connaissances, ainsi que les Service Packs recommandés :

  • L’un des systèmes d’exploitation suivants avec MSMQ installé (il est inclus en tant qu’option sur les quatre systèmes d’exploitation) : Windows 2000 Professionnel (ou serveur) ou Windows XP professionnel (ou serveur).

Cet article suppose également que vous êtes familiarisé avec les éléments suivants :

  • MESSAGE
  • Utilisation des outils à partir de l’invite de commandes

retour au début

Écrire et lire à partir de MSMQ

L' System.Messaging espace de noms dans .NET Framework dispose des classes dont vous devez disposer pour lire et écrire dans MSMQ. Pour créer une petite application Windows qui imite un système de paiement électronique en ligne, procédez comme suit :

  1. Ouvrez Visual Studio .NET ou Visual Studio 2005.

  2. Créez une nouvelle application Windows dans Visual C#, puis nommez-la MSMQ.

  3. Pour afficher l' Explorateur de solutions s’il ne s’affiche pas, appuyez sur CTRL + ALT + L. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur Références, puis cliquez sur Ajouter une référence.

  4. Sous l’onglet .net , sélectionnez le fichier de System.Messaging.dll dans la liste des fichiers . dll . Cliquez sur Sélectionner, puis sur OK.

    Notes

    Dans Visual Studio 2005, cliquez sur le System.Messaging.dll fichier dans la liste des dll, puis cliquez sur OK.

  5. Form1.cs est ouvert en mode création. S’il n’est pas ouvert, double-cliquez sur Form1.cs dans l' Explorateur de solutions.

  6. Appuyez sur CTRL + ALT + X pour ouvrir la boîte à outils. Dans la boîte à outils, cliquez sur l’onglet Windows Forms .

  7. À partir de la boîte à outils, faites glisser les éléments suivants au milieu de Form1:

    • Quatre lignes de chaque étiquette et zone de texte (positionnée à droite de chaque étiquette).
    • Sous étiquettes et zones de texte, faites glisser deux contrôles bouton vers Form1.
  8. Cliquez avec le bouton droit sur les contrôles, cliquez sur Propriétés, puis définissez la propriété Text pour les étiquettes sur la valeur suivante (dans l’ordre) :

    • Payer à :
    • Votre nom:
    • Enchère
    • Date d’échéance :
  9. Dans la boîte de dialogue Propriétés , définissez la propriété Text de Button1 sur Envoyer le paiement, et définissez la propriété texte de Button2 sur traiter le paiement.

  10. Cette application fonctionne avec une file d’attente privée que vous devez d’abord créer dans la console de gestion de l’ordinateur. Pour cela, procédez comme suit :

    1. Sur le bureau, cliquez avec le bouton droit sur poste de travail, puis cliquez sur gérer.
    2. Développez le nœud services et applications pour rechercher MSMQ.

    Notes

    Si vous ne trouvez pas MSMQ, il n’est pas installé.

  11. Développez Message Queuing, cliquez avec le bouton droit sur files d’attente privées, pointez sur nouveau, puis cliquez sur file d’attente privée.

  12. Dans la zone nom de la file d’attente , tapez BILLPAY, puis cliquez sur OK.

    Notes

    N’activez pas la case à cocher transactionnel . Laissez la console Gestion de l’ordinateur ouverte, car vous y accédez plus tard pour afficher les messages.

  13. En haut du code dans Form1, ajoutez deux USING instructions avant la déclaration de classe pour inclure les classes supplémentaires qui se trouvent dans l' System.Messaging espace de noms et les System.Text espaces de noms. (L' System.Text espace de noms est destiné à l’utilisation de la StringBuilder classe, une nouvelle classe .NET Framework qu’il est préférable d’utiliser lors de la concaténation de chaînes.)

    using System.Messaging;
    using System.Text;
    
  14. Créer une structure qui contient des variables pour contenir les données qui définissent un paiement. Pour créer la structure, ajoutez le code suivant après la procédure main :

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. Ajoutez le code dans les étapes suivantes à l' Click événement de button1 .

    1. Définissez les propriétés de la structure sur les valeurs des éléments Form comme suit :

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. Créez une instance de la Message classe, puis définissez la Body propriété sur la payment structure :

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. Pour envoyer un message à MSMQ, créez une instance de la MessageQueue classe et appelez la Send méthode qui transmet l' Message objet. La MessageQueue classe est le wrapper qui gère l’interaction avec MSMQ.

      Notes

      La syntaxe permettant de définir le chemin d’accès à la file d’attente privée que vous avez créée dans la console de gestion de l’ordinateur. Les files d’attente privées prennent la forme machinename\Private$\queuename . Les ordinateurs hôtes locaux sont référencés à l’aide d’un point ou d’un point (affiché sous la forme .).

      MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
      msgQ.Send(msg);
      

      Le code existe maintenant pour envoyer un message à MSMQ. Le .NET Framework sérialise automatiquement le message à l’aide d’un XMLMessageFormatter objet. Cet objet est créé de manière implicite lors de l’envoi de messages.

  16. Ajoutez le code dans les étapes suivantes à l' Click événement Button2. Le button2_Click Gestionnaire d’événements reçoit et traite le message de paiement qui est envoyé dans le button1 Gestionnaire d’événements.

    1. La première ligne de code est identique à la ligne de code qui se trouve dans le premier gestionnaire d’événements :

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. Créez un tableau de types à transmettre à la XMLMessageFormatter classe.

      Notes

      Cette classe doit être créée de manière explicite lors de la réception de messages. Le constructeur de la XMLMessageFormatter classe prend un tableau de chaînes de noms de types ou, de préférence, un Type tableau de types :

      Payment myPayment=new Payment();
      Object o=new Object();
      System.Type[] arrTypes=new System.Type [2];
      arrTypes[0] = myPayment.GetType();
      arrTypes[1] = o.GetType();
      msgQ.Formatter = new XmlMessageFormatter(arrTypes);
      myPayment=((Payment)msgQ.Receive().Body);
      

      Ces types indiquent XMLMessageFormatter à la procédure de désérialisation du message.

    3. Les messages sont reçus en appelant la Receive méthode. Accéder Body à la propriété pour lire le contenu du message. La Body propriété renvoie un objet, par conséquent, l’objet doit être converti en type de paiement pour extraire le contenu sous une forme utilisable :

      StringBuilder sb = new StringBuilder();
      sb.Append("Payment paid to: " + myPayment.Payor);
      sb.Append("\n");
      sb.Append("Paid by: " + myPayment.Payee);
      sb.Append("\n");
      sb.Append("Amount: $" + myPayment.Amount.ToString());
      sb.Append("\n");
      sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
      
    4. Créez un message pour afficher les résultats :

      MessageBox.Show(sb.ToString(), "Message Received!");
      

retour au début

Liste complète du code (Form1.cs)

using System.Messaging;
using System.Text;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.TextBox textBox4;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;
        public Form1()
        {
        // Required for Windows Form Designer support
            InitializeComponent();
        // TODO: Add any constructor code after InitializeComponent call
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // label1
            this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(104, 32);
            this.label1.TabIndex = 0;
            this.label1.Text = "Pay To:";
            // label2
            this.label2.Location = new System.Drawing.Point(8, 80);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(104, 32);
            this.label2.TabIndex = 1;
            this.label2.Text = "Your Name:";
            // label3
            this.label3.Location = new System.Drawing.Point(8, 136);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(112, 32);
            this.label3.TabIndex = 2;
            this.label3.Text = "Amount:";
            // label4
            this.label4.Location = new System.Drawing.Point(8, 184);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(104, 40);
            this.label4.TabIndex = 3;
            this.label4.Text = "Due To:";
            // textBox1
            this.textBox1.Location = new System.Drawing.Point(152, 24);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(128, 20);
            this.textBox1.TabIndex = 4;
            this.textBox1.Text = "textBox1";
            // textBox2
            this.textBox2.Location = new System.Drawing.Point(160, 80);
            this.textBox2.Name = "textBox2";
            this.textBox2.TabIndex = 5;
            this.textBox2.Text = "textBox2";
            // textBox3
            this.textBox3.Location = new System.Drawing.Point(160, 128);
            this.textBox3.Name = "textBox3";
            this.textBox3.Size = new System.Drawing.Size(112, 20);
            this.textBox3.TabIndex = 6;
            this.textBox3.Text = "textBox3";
            // textBox4
            this.textBox4.Location = new System.Drawing.Point(160, 184);
            this.textBox4.Name = "textBox4";
            this.textBox4.Size = new System.Drawing.Size(120, 20);
            this.textBox4.TabIndex = 7;
            this.textBox4.Text = "textBox4";
            // button1
            this.button1.Location = new System.Drawing.Point(8, 232);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(104, 40);
            this.button1.TabIndex = 8;
            this.button1.Text = "Send Payment";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // button2
            this.button2.Location = new System.Drawing.Point(160, 232);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(120, 40);
            this.button2.TabIndex = 9;
            this.button2.Text = "Process Payment";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.textBox4);
            this.Controls.Add(this.textBox3);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
        }
        #endregion
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
        private void button1_Click(object sender, System.EventArgs e)
        {
            Payment myPayment;
            myPayment.Payor = textBox1.Text;
            myPayment.Payee = textBox2.Text;
            myPayment.Amount = Convert.ToInt32(textBox3.Text);
            myPayment.DueDate = textBox4.Text;
            System.Messaging.Message msg = new System.Messaging.Message();
            msg.Body=myPayment;
            MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
            msgQ.Send(msg);
        }
        private void button2_Click(object sender, System.EventArgs e)
        {
            MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
            Payment myPayment=new Payment();
            Object o=new Object();
            System.Type[] arrTypes=new System.Type [2];
            arrTypes[0] = myPayment.GetType();
            arrTypes[1] = o.GetType();
            msgQ.Formatter = new XmlMessageFormatter(arrTypes);
            myPayment=((Payment)msgQ.Receive().Body);
            StringBuilder sb = new StringBuilder();
            sb.Append("Payment paid to: " + myPayment.Payor);
            sb.Append("\n");
            sb.Append("Paid by: " + myPayment.Payee);
            sb.Append("\n");
            sb.Append("Amount: $" + myPayment.Amount.ToString());
            sb.Append("\n");
            sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
            MessageBox.Show(sb.ToString(), "Message Received!");
        }
        public struct Payment
        {
            public string Payor,Payee;
            public int Amount;
            public string DueDate;
        }
    }
}

Notes

Le code doit être modifié dans Visual Studio 2005. Lorsque vous créez un projet Windows Forms, Visual C# ajoute par défaut un formulaire au projet. Ce formulaire est nommé Form1. Les deux fichiers qui représentent le formulaire sont nommés Form1.cs et Form1.Designer.cs. Vous écrivez votre code dans Form1.cs. Le fichier Designer.cs est l’endroit où le Concepteur Windows Forms écrit le code qui implémente toutes les actions que vous avez effectuées en ajoutant des contrôles. Pour plus d’informations sur le Concepteur Windows Forms dans Visual C# 2005, voir Creating a Project (Visual c#)

retour au début

Vérifier le code

  1. Dans le menu débogage , cliquez sur Démarrer.

  2. Tapez des valeurs dans chaque zone de texte, puis cliquez sur Envoyer le paiement.

  3. Revenez à la console de gestion de l’ordinateur. Cliquez sur le dossier messages de file d’attente dans les files d’attente privées sous BILLPAY, puis vérifiez que MSMQ a reçu un message (indiqué par une icône d’enveloppe).

  4. Cliquez avec le bouton droit sur le message, cliquez sur Propriétés, puis sur l’onglet corps . Vous remarquez le message de paiement.

    Notes

    Le contenu du message de paiement est sérialisé au format XML.

  5. Revenez à l’application Windows de paiement électronique, puis cliquez sur le bouton paiement en cours . Une boîte de message s’affiche pour confirmer la réception d’un message et l’affichage du message.

retour au début

Résoudre les problèmes

  • L’absence d’une file d’attente privée n’est généralement un problème que sur Windows 2000 professionnel et Windows XP professionnel. Windows 2000 Server et Windows XP Server permettent l’utilisation de la file d’attente publique.

  • Le passage des arguments corrects à XMLMessageFormatter() peut être délicat. Dans cet exemple, des exceptions sont levées si l’objet ou les types de paiement ne sont pas inclus dans le tableau de types passé au constructeur.

retour au début