XmlMessageFormatter 类

定义

使用基于 XSD 架构定义的 XML 格式,将对象序列化和反序列化为消息体或从消息体序列化和反序列化对象。

public ref class XmlMessageFormatter : ICloneable, System::Messaging::IMessageFormatter
public class XmlMessageFormatter : ICloneable, System.Messaging.IMessageFormatter
type XmlMessageFormatter = class
    interface IMessageFormatter
    interface ICloneable
Public Class XmlMessageFormatter
Implements ICloneable, IMessageFormatter
继承
XmlMessageFormatter
实现

示例

下面的代码示例包括三段代码:服务器组件、订单类和客户端代码。 order 类可由 XSD.exe 实用工具用于生成服务器在传入消息中识别的架构。 架构是一个 XML 格式化文件,用于描述 类的“形状”。 然后,可以在客户端使用此架构来生成客户端特定的订单类,该类与服务器类共享相同的架构。

下面的代码示例表示通过消息队列接收订单的服务器组件。 消息正文应是其架构与下面的 Order.cs 类匹配的 order 对象。 服务器进程或应用程序反序列化订单。

#using <System.dll>
#using <System.Messaging.dll>

using namespace System;
using namespace System::Messaging;

// placeholder; see complete definition elsewhere in this section
public ref class Order
{
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( "Processing Orders" );
   String^ queuePath = ".\\orders";
   EnsureQueueExists( queuePath );
   MessageQueue^ queue = gcnew MessageQueue( queuePath );
   array<String^>^temp0 = {"Order"};
   (dynamic_cast<XmlMessageFormatter^>(queue->Formatter))->TargetTypeNames = temp0;
   while ( true )
   {
      Order^ newOrder = dynamic_cast<Order^>(queue->Receive()->Body);
      newOrder->ShipItems();
   }
}
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);
         }
     }
 }
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
    
    
    ' 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
End Class

下面的代码示例表示 order 类,该类为服务器上的应用程序接收和反序列化的 order 对象提供架构。

using namespace System;
public ref class Order
{
public:
   int itemId;
   int quantity;
   String^ address;
   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. */
   }

};
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. */
     }
 }
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
End Class

与服务器上的应用程序交互的任何客户端应用程序都必须通过将本地定义的顺序类中的信息序列化到消息正文中来向服务器发送消息。 本地定义的顺序类必须具有与服务器定义的顺序类相同的架构,服务器上的应用程序将尝试反序列化消息正文。 XSD.exe 实用工具允许服务器上的应用程序的管理器创建和分发客户端必须用于序列化发送到服务器的消息的架构。

当客户端应用程序的管理器收到订单类的架构时,将再次使用 XSD.exe 实用工具从架构生成特定于客户端的订单类。 下面的客户端代码示例中使用的是此类,而不是服务器的 order 类 (XSD.exe 实用工具会导致架构生成的类与原始类) 同名。 此新 order 类用于将订单序列化到消息正文中。

下面的代码示例是客户端处理,用于序列化订单并将与订单关联的信息发送到队列。 该代码将 Item、Quantity 和 Address 信息与由 XSD.exe 实用工具为 Order.cs 类生成的架构元素相关联。 订单将发送到本地计算机上的 Orders 队列。

#using <System.dll>
#using <System.Messaging.dll>

using namespace System;
using namespace System::Messaging;

// placeholder; see complete definition elsewhere in this section
public ref class Order
{
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 = ".\\orders";
   EnsureQueueExists( queuePath );
   MessageQueue^ queue = gcnew MessageQueue( queuePath );
   Order^ orderRequest = gcnew 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();
}
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);
         }
     }
 }
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
    
    ' 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
End Class

从服务器上的 order 类生成架构后,可以修改 类。 除非架构发生更改,否则无需重新分发架构。 分发架构并生成客户端顺序类后,只要架构本身未修改,该客户端类也可以独立于服务器的 order 类进行修改。 这两个类已变得松散耦合。

注解

XmlMessageFormatter是 实例用于序列化写入队列的消息的默认格式化程序MessageQueue。 创建 实例 MessageQueue时,会为你创建一个 XmlMessageFormatter 实例 MessageQueue并与 相关联。 可以通过在代码中创建格式化程序并将其分配给 FormatterMessageQueue属性来指定不同的格式化程序。

队列的默认 XmlMessageFormatter 实例可用于写入队列,但在格式化程序上设置 TargetTypesTargetTypeNames 属性之前,它不能用于从队列中读取数据。 可以在默认格式化程序实例上设置其中一个或两个值,也可以创建格式化程序的新实例,并通过将这些值作为参数传递给相应的 XmlMessageFormatter 构造函数来自动设置这些值。

当指定 TargetTypes 而不是 TargetTypeNames时,将在编译时而不是读取时检查类型是否存在,从而降低出错的可能性。 TargetTypeNames 要求每个条目都是完全限定的,并指定其程序集名称。 此外,在使用多个并发版本时,还必须将版本号追加到目标类型名称中。

TargetTypeNamesTargetTypes 属性告诉格式化程序在反序列化消息时要尝试匹配的架构。 这允许格式化程序解释消息正文。

在消息正文中序列化的实例必须符合类型数组中表示的架构之一。 使用 Receive 方法读取消息时, 方法将创建与标识的架构对应的类型的对象,并将消息正文读入其中。

从队列读取时,只需设置两个属性中的一个,但你可以同时设置这两个属性。 类型集是两个属性的组合集。 决定使用哪个属性特定于应用程序。 如果消息正文包含一个类型,其架构与任一属性的数组中的任何类型都不匹配,则在读取消息时将引发异常。

XmlMessageFormatter是松散耦合的基于 XML 的消息传送的关键组件。 XSD.exe 实用工具使用 XML 格式来生成 XML 架构,例如,使用 实用工具序列化应用程序使用的类时。 类必须具有一个无参数的构造函数。

当实用工具基于你分发的用于描述类数据的架构生成类时,将在反向进程中再次使用该格式。 通过使用 实用工具和它生成的 XML 架构,可以在类的实现发生更改后每次重新编译类时避免redistributing.dll文件。 只要架构在客户端或服务器上不更改,任一端的其他更改不会影响另一端。

构造函数

XmlMessageFormatter()

初始化 XmlMessageFormatter 类的新实例但不设置目标类型。

XmlMessageFormatter(String[])

初始化 XmlMessageFormatter 类的新实例,并将传入的目标类型设置为(完全限定)字符串值数组。

XmlMessageFormatter(Type[])

初始化 XmlMessageFormatter 类的新实例,并将传入的目标类型设置为对象类型的数组。

属性

TargetTypeNames

指定可能的类型集,这些类型将由格式化程序从提供的消息进行反序列化。

TargetTypes

指定可能的类型集,这些类型将由格式化程序从提供的消息进行反序列化。

方法

CanRead(Message)

确定格式化程序是否可以反序列化消息。

Clone()

创建 XmlMessageFormatter 类的实例,此实例的读/写属性(目标类型集)与当前 XmlMessageFormatter 实例相同。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
Read(Message)

从给定的消息中读取内容,并创建包含反序列化消息的对象。

ToString()

返回表示当前对象的字符串。

(继承自 Object)
Write(Message, Object)

将对象序列化为消息体。

适用于

另请参阅