XmlMessageFormatter クラス

XSD スキーマ定義の XML 書式を使用して、メッセージ本文との間でオブジェクトをシリアル化および逆シリアル化します。

この型のすべてのメンバの一覧については、XmlMessageFormatter メンバ を参照してください。

System.Object
   System.Messaging.XmlMessageFormatter

Public Class XmlMessageFormatter
   Implements IMessageFormatter, ICloneable
[C#]
public class XmlMessageFormatter : IMessageFormatter, ICloneable
[C++]
public __gc class XmlMessageFormatter : public IMessageFormatter,
   ICloneable
[JScript]
public class XmlMessageFormatter implements IMessageFormatter,
   ICloneable

スレッドセーフ

この型の public static (Visual Basicでは Shared) のすべてのメンバは、マルチスレッド操作で安全に使用できます。インスタンスのメンバの場合は、スレッドセーフであるとは限りません。

解説

XmlMessageFormatter は、キューに書き込まれたメッセージをシリアル化するために MessageQueue のインスタンスが使用する既定のフォーマッタです。 MessageQueue のインスタンスを作成するときに、 XmlMessageFormatter のインスタンスが作成され、 MessageQueue に関連付けられます。別のフォーマッタを指定するには、コード内でそのフォーマッタを作成して MessageQueueFormatter プロパティに割り当てます。

キューの既定の XmlMessageFormatter インスタンスを使用して、キューに書き込むことができますが、これを使用してキューから読み取るには、フォーマッタで TargetTypes プロパティまたは TargetTypeNames プロパティを設定する必要があります。既定のフォーマッタのインスタンスで、これらの値の一方または両方を設定できます。または、フォーマッタの新しいインスタンスを作成し、値を適切な XmlMessageFormatter コンストラクタに引数として渡すことによって、自動的に設定できます。

TargetTypeNames ではなく TargetTypes を指定する場合は、読み取り時ではなくコンパイル時に型の存在を確認することで、エラーの可能性が抑制されます。 TargetTypeNames では、すべてのエントリが完全に限定され、アセンブリ名が指定されている必要があります。さらに、複数のバージョンを同時に操作する場合は、対象の型名にバージョン番号も追加する必要があります。

TargetTypeNames プロパティおよび TargetTypes プロパティを使うと、メッセージの逆シリアル化時に、フォーマッタがどのスキーマを一致させるかを指示できます。これにより、フォーマッタがメッセージ本文を解釈できます。

メッセージ本文でシリアル化されるインスタンスは、型配列で表されたスキーマの 1 つに従っている必要があります。 Receive メソッドを使用してメッセージを読み取る場合は、識別されたスキーマに対応する型のオブジェクトがこのメソッドによって作成され、そこにメッセージ本文が読み込まれます。

キューから読み取るときに設定する必要があるのは、2 つのプロパティのうちの 1 つだけですが、両方を設定することもできます。型のセットとは、2 つのプロパティの型を結合したものです。どのプロパティを使用するかは、アプリケーションによって異なります。メッセージ本文に、両方のプロパティの配列内のどの型ともスキーマが一致しない型が含まれている場合は、メッセージの読み取り時に例外がスローされます。

XmlMessageFormatter は、粗結合された重要な XML ベースのメッセージ処理コンポーネントです。XSD.exe ユーティリティは、ユーティリティを使用してアプリケーションで使用するクラスをシリアル化するときなどに、XML 書式を使用して XML スキーマを生成します。この書式は、クラス データを記述するために配布するスキーマに基づいてユーティリティがクラスを生成するときに、逆のプロセスで再び使用されます。ユーティリティとユーティリティが生成する XML スキーマを使用すると、クラスの実装が変更された後、クラスを再コンパイルするたびに .dll ファイルを再配布する必要がなくなります。クライアントまたはサーバーでスキーマが変更された場合を除き、どちらか一方でその他の変更が行われても、もう一方に影響を与えることはありません。

使用例

[Visual Basic, C#, C++] サーバー コンポーネント、order クラス、およびクライアント コードの 3 つのコードが含まれている例を次に示します。XSD.exe ユーティリティで order クラスを使用すると、受信メッセージ内でサーバーが認識するスキーマを生成できます。スキーマは、XML 形式のファイルで、クラスの "形" を記述します。次にクライアント側でこのスキーマを使用して、サーバー クラスと同じスキーマを共有するクライアント固有の order クラスを生成できます。

[Visual Basic, C#, C++] メッセージ キューを通じてオーダーを受信するサーバー コンポーネントを表すコードを次に示します。メッセージの本文は、スキーマが下の Order.cs クラスと一致するオーダー オブジェクトです。サーバー プロセスまたはサーバー アプリケーションが、オーダーを逆シリアル化します。

 
Imports System
Imports System.Messaging



Public Class Server
    
    
    Public Shared Sub Main()
        
        Console.WriteLine("Processing Orders")
        
        Dim queuePath As String = ".\orders"
        EnsureQueueExists(queuePath)
        Dim queue As New MessageQueue(queuePath)
        CType(queue.Formatter, XmlMessageFormatter).TargetTypeNames = New String() {"Order"}
        
        While True
            Dim newOrder As Order = CType(queue.Receive().Body, Order)
            newOrder.ShipItems()
        End While
    End Sub 'Main
    
    
    ' Creates the queue if it does not already exist.
    Public Shared Sub EnsureQueueExists(path As String)
        If Not MessageQueue.Exists(path) Then
            MessageQueue.Create(path)
        End If
    End Sub 'EnsureQueueExists
End Class 'Server

[C#] 
using System;
using System.Messaging;
 
 public class Server{
 
     public static void Main(){
 
         Console.WriteLine("Processing Orders");
 
         string queuePath = ".\\orders";
         EnsureQueueExists(queuePath);
         MessageQueue queue = new MessageQueue(queuePath);
         ((XmlMessageFormatter)queue.Formatter).TargetTypeNames = new string[]{"Order"};
 
         while(true){
             Order newOrder = (Order)queue.Receive().Body;
             newOrder.ShipItems();
         }
     }
 
     // Creates the queue if it does not already exist.
     public static void EnsureQueueExists(string path){
         if(!MessageQueue.Exists(path)){
             MessageQueue.Create(path);
         }
     }
 }

[C++] 
#using <mscorlib.dll>
#using <System.dll>
#using <System.Messaging.dll>
using namespace System;
using namespace System::Messaging;

public __gc class Order

// placeholder; see complete definition elsewhere in this section

{
public:
    void ShipItems()
    {
    }
};

// Creates the queue if it does not already exist.
void EnsureQueueExists(String* path){
    if(!MessageQueue::Exists(path)){
        MessageQueue::Create(path);
    }
}

int main(){

    Console::WriteLine(S"Processing Orders");

    String* queuePath = S".\\orders";
    EnsureQueueExists(queuePath);
    MessageQueue* queue = new MessageQueue(queuePath);

    String* temp0 [] = {S"Order"};
    (dynamic_cast<XmlMessageFormatter*>(queue->Formatter))->TargetTypeNames = temp0;

    while(true){
        Order* newOrder = dynamic_cast<Order*>(queue->Receive()->Body);
        newOrder->ShipItems();
    }
}

[Visual Basic, C#, C++] このコード例は、サーバーのアプリケーションが受信して逆シリアル化するオーダー オブジェクトに対するスキーマを提供する order クラスを表しています。

 
Imports System
Imports Microsoft.VisualBasic

Public Class Order
    
    Public itemId As Integer
    Public quantity As Integer
    Public address As String
    
    
    Public Sub ShipItems()
        
        Console.WriteLine("Order Placed:")
        Console.WriteLine(ControlChars.Tab & "Item ID  : {0}", itemId)
        Console.WriteLine(ControlChars.Tab & "Quantity : {0}", quantity)
        Console.WriteLine(ControlChars.Tab & "Ship To  : {0}", address)

        ' Add order to the database.
        ' Insert code here.
 
    End Sub 'ShipItems 
End Class 'Order 

[C#] 
using System;
 
 public class Order{
 
     public int itemId;
     public int quantity;
     public string address;
 
     public void ShipItems(){
 
         Console.WriteLine("Order Placed:");
         Console.WriteLine("\tItem ID  : {0}",itemId);
         Console.WriteLine("\tQuantity : {0}",quantity);
         Console.WriteLine("\tShip To  : {0}",address);
 
         // Add order to the database.
         /* Insert code here. */
 
     }
 }

[C++] 
#using <mscorlib.dll>
using namespace System;
 
public __gc class Order{
 
public:
     int itemId;
     int quantity;
     String* address;

     void ShipItems(){
         Console::WriteLine(S"Order Placed:");
         Console::WriteLine(S"\tItem ID  : {0}", __box(itemId));
         Console::WriteLine(S"\tQuantity : {0}", __box(quantity));
         Console::WriteLine(S"\tShip To  : {0}",address);
 
         // Add order to the database.
         /* Insert code here. */
     }
};

[Visual Basic, C#, C++] サーバーのアプリケーションとやり取りするすべてのクライアント アプリケーションは、ローカルに定義された order クラスの情報をメッセージ本文にシリアル化して、メッセージをサーバーに送信する必要があります。ローカルに定義された order クラスには、サーバーのアプリケーションがメッセージ本文を逆シリアル化するサーバー定義の order クラスと同じスキーマが必要です。XSD.exe ユーティリティを使用すると、サーバーのアプリケーション マネージャは、サーバーに送信するメッセージのシリアル化にクライアントが使用するスキーマを作成および配布できます。

[Visual Basic, C#, C++] クライアント アプリケーション マネージャが order クラスのスキーマを受信すると、XSD.exe ユーティリティを再び使用してスキーマからクライアント固有の order クラスを生成します。下のクライアント コード例では、サーバーの order クラスではなく、このクラスを使用します。XSD.exe ユーティリティは、スキーマ生成クラスに元のクラスと同じ名前を付けます。この新しい order クラスを使用して、オーダーをメッセージ本文にシリアル化します。

[Visual Basic, C#, C++] order をシリアル化し、オーダーに関連付けられた情報をキューに送信するクライアント側の処理を行うコードを次に示します。このコードは、XSD.exe ユーティリティで Order.cs クラス用に生成されたスキーマの要素に品目、数量、住所の情報を関連付けます。オーダーは、ローカル コンピュータの "orders" キューに送信されます。

 
Imports System
Imports System.Messaging

Class Client
    
    
    Public Shared Sub Main()
        
        Dim queuePath As String = ".\orders"
        EnsureQueueExists(queuePath)
        Dim queue As New MessageQueue(queuePath)
        
        Dim orderRequest As New Order()
        orderRequest.itemId = 1025
        orderRequest.quantity = 5
        orderRequest.address = "One Microsoft Way"
        
        queue.Send(orderRequest)
        ' This line uses a new method you define on the Order class:
        ' orderRequest.PrintReceipt()

    End Sub 'Main
    
    ' Creates the queue if it does not already exist.
    Public Shared Sub EnsureQueueExists(path As String)
        If Not MessageQueue.Exists(path) Then
            MessageQueue.Create(path)
        End If
    End Sub 'EnsureQueueExists
End Class 'Client 

[C#] 
using System;
using System.Messaging;
 
 class Client{
 
     public static void Main(){
 
         string queuePath = ".\\orders";
         EnsureQueueExists(queuePath);
         MessageQueue queue = new MessageQueue(queuePath);
 
         Order orderRequest = new Order();
         orderRequest.itemId = 1025;
         orderRequest.quantity = 5;
         orderRequest.address = "One Microsoft Way";
 
         queue.Send(orderRequest);
         // This line uses a new method you define on the Order class:
         // orderRequest.PrintReceipt();
     }
 
     // Creates the queue if it does not already exist.
     public static void EnsureQueueExists(string path){
         if(!MessageQueue.Exists(path)){
             MessageQueue.Create(path);
         }
     }
 
 }

[C++] 
#using <mscorlib.dll>
#using <System.dll>
#using <System.Messaging.dll>
using namespace System;
using namespace System::Messaging;

public __gc class Order

// placeholder; see complete definition elsewhere in this section

{
public:
    int itemId;
    int quantity;
    String* address;

    void ShipItems()
    {
    }
};

// Creates the queue if it does not already exist.
void EnsureQueueExists(String* path){
    if(!MessageQueue::Exists(path)){
        MessageQueue::Create(path);
    }
}

int main(){

    String* queuePath = S".\\orders";
    EnsureQueueExists(queuePath);
    MessageQueue* queue = new MessageQueue(queuePath);

    Order* orderRequest = new Order();
    orderRequest->itemId = 1025;
    orderRequest->quantity = 5;
    orderRequest->address = S"One Microsoft Way";

    queue->Send(orderRequest);
    // This line uses a new method you define on the Order class:
    // orderRequest.PrintReceipt();
}

[Visual Basic, C#, C++] スキーマがサーバーの order クラスから生成された後でも、クラスを変更できます。スキーマを変更した場合を除いて、スキーマを再配布する必要はありません。スキーマを配布し、クライアント側の order クラスを生成した後は、スキーマそのものが変更されていない場合、そのクライアント クラスもサーバーの order クラスから独立して変更できます。2 つのクラスは、粗結合されています。

[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン 言語のフィルタ をクリックします。

必要条件

名前空間: System.Messaging

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ

アセンブリ: System.Messaging (System.Messaging.dll 内)

参照

XmlMessageFormatter メンバ | System.Messaging 名前空間 | MessageQueue | ActiveXMessageFormatter | BinaryMessageFormatter | IMessageFormatter