How to write to and read from Microsoft Message Queuing in Visual C# (815811)
The information in this article applies to:
- Microsoft Windows 2000 Server
- Microsoft Windows 2000 Professional
- Microsoft Visual C# .NET (2002)
- Microsoft Visual C# .NET (2003)
- Microsoft Windows XP Professional
- Microsoft Message Queue Server (MSMQ) 1.0
- Microsoft Visual C# 2005, Express Edition
For a Microsoft Visual Basic .NET version of this
article, see
315698. IN THIS TASKSUMMARYThis article describes the following: - How to create a message and send it
to Microsoft Message Queuing in a Windows application.
- How to read from a private queue and to deserialize the message
contents for display.
back to the
topRequirementsThe following items describe the recommended hardware, software,
network infrastructure, skills and knowledge, and service packs that are
required:
- One of the following operating systems with Microsoft Message Queuing installed (it is included as an option on the four operating
systems): Windows 2000 Professional (or Server), or Windows XP
Professional (or Server).
This article also assumes that you are familiar with the following: - Microsoft Message Queuing
- Using tools from the command
prompt
back to the topWrite to and Read from Microsoft Message QueuingThe System.Messaging namespace in the Microsoft .NET Framework has the classes that
you must have to read from and write to Microsoft Message Queuing. To create a small Windows application that mimics an online bill
payment system, follow these steps:
- Open Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
- Create a new Windows application in Visual C# , and
then name it MSMQ.
- To
display Solution
Explorer if
it does not appear, press CTRL+ALT+L. In Solution Explorer, right-click References, and then click Add Reference.
- On the
.NET tab, select the System.Messaging.dll
file in the list of .dll files. Click Select, and then click OK.
Note In Visual Studio 2005, click the System.Messaging.dll
file in the list of DLLs, and then click OK. - Form1.cs is open in Design view. If it is not open, double-click Form1.cs
in Solution Explorer.
- Press CTRL+ALT+X to open the toolbox. In the
Toolbox, click the Windows Forms tab.
- From the
Toolbox, drag the following to the middle of
Form1:
- 4 rows each of a Label and
a Textbox (positioned to the right of each label).
- Under the
labels and text boxes, drag two Button controls onto Form1.
- Right-click the controls, click
Properties, and then set the Text property for the
labels to the following (in order):
- Pay To:
- Your Name:
- Amount:
- Due Date:
- In the Properties dialog
box, set the Text property of
button1 to Send Payment, and set the
Text property of button2 to Process
Payment.
- This application works with a private queue that you must
first create in the Computer Management console. To do this, follow these steps:
- On the desktop,
right-click My Computer, and then click
Manage.
- Expand the Services
and Applications node to find Message Queuing.
Note If you do not
find Message Queuing, it is not installed.
- Expand Message
Queuing, right-click Private Queues, point to
New, and then click Private Queue.
- In the Queue name box, type
billpay,
and then click OK.
Note Do
not select the Transactional check box. Leave the Computer
Management console open because you return to it later to view messages.
- At the top of the code in Form1, add two USING
statements before
the class declaration to include the additional classes that reside in the System.Messaging namespace and the System.Text namespaces. (The System.Text namespace is for the use of the StringBuilder class, a new .NET Framework class that it is best to use when you
concatenate strings.)
using System.Messaging;
using System.Text;
- Create a structure that contains variables to hold the
data that defines a payment. To create the structure, add the following code
after the Main procedure:
public struct Payment
{
public string Payor,Payee;
public int Amount;
public string DueDate;
} - Add the code in the following steps to the Click event of button1.
- Set the properties
of the structure to values of the form elements as follows:
Payment myPayment;
myPayment.Payor = textBox1.Text;
myPayment.Payee = textBox2.Text;
myPayment.Amount = Convert.ToInt32(textBox3.Text);
myPayment.DueDate = textBox4.Text; - Create an instance of the Message class, and then set the Body property to the payment structure:
System.Messaging.Message msg = new System.Messaging.Message();
msg.Body=myPayment; - To send a message to Microsoft Message Queuing,
create an instance of the MessageQueue class and call the Send method that passes in the Message object.
The MessageQueue class is the wrapper that manages the interaction with Microsoft
Message Queuing.
Notice the syntax for setting the path
of the private queue that you created in the Computer
Management console. Private queues take the form
machinename\Private$\queuename. Local host machines are referenced with a dot
or a period
(shown as ".").MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
msgQ.Send(msg); The code now
exists to send a message to Microsoft Message Queuing. The .NET Framework automatically serializes the message by using an XMLMessageFormatter object. This
object
is implicitly created when messages
are sent.
- Add the code in the following steps to the Click event of button2. The button2_Click event handler receives and processes the payment message that is
sent in the button1 event handler.
- The first line of code is the same as the line of code that is in the first event handler:
MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay"); - Create an array of types to pass to the
XMLMessageFormatter class.
Note This class must be explicitly created
when receiving messages. The constructor of the XMLMessageFormatter class takes
either a string array of type names or, more preferably, a Type array of 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); These types tell the XMLMessageFormatter how to deserialize the
message. - Messages are received by calling the Receive method.
Access the Body property to read the message contents. The Body property returns an object, therefore
the object has
to
be cast to the payment type to retrieve the contents in a usable form:
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)); - Create a message box to display the results:
MessageBox.Show(sb.ToString(), "Message Received!");
back to the topComplete Code Listing (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;
}
}
}
Note The code should be changed in Visual Studio 2005. When you create a Windows Forms project, Visual C# adds one form to the project by default. This form is named Form1. The two files that represent the form are named Form1.cs and Form1.designer.cs. You write your code in Form1.cs. The Designer.cs file is where the Windows Forms Designer writes the code that implements all the actions that you performed by adding controls.
For more information about the Windows Forms Designer in Visual C# 2005, visit the following Microsoft Web site: back to the topVerify the Code- On the Debug menu, click
Start.
- Type values in each text box,
and then click Send Payment.
- Return to the Computer Management console. Click the Queue messages folder in Private Queues under billpay, and then verify that Microsoft Message Queuing received a
message (indicated by an envelope icon).
- Right-click the message, click Properties, and then click the Body tab. You notice
the payment message.
Note The contents of the payment message are serialized as XML.
- Return to the bill payment Windows application, and then click the Process Payment button. You see a message box that confirms the receipt of a
message and displays the message.
back to the topTroubleshoot- The lack of a private queue is generally
an issue only on Windows 2000 Professional and Windows XP Professional. Windows
2000 Server and Windows XP Server permit the use of the public queue.
- Passing the correct arguments to XMLMessageFormatter()
can be tricky. In this example, exceptions are thrown if either the object or
the Payment Types are not included in the Type array that is passed to the
constructor.
back to the
topREFERENCESFor more information about Microsoft Message Queuing,
visit the following Microsoft Web sites:
Modification Type: | Major | Last Reviewed: | 1/18/2006 |
---|
Keywords: | kbServer kbForms kbWindowsForms kbHOWTOmaster KB815811 kbAudDeveloper |
---|
|
|
©2004 Microsoft Corporation. All rights reserved.
|
|