XmlMessageFormatter 类

定义

使用基于 XSD 架构定义的 XML 格式,将对象序列化和反序列化为消息体或从消息体序列化和反序列化对象。Serializes and deserializes objects to or from the body of a message, using the XML format based on the XSD schema definition.

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
实现

示例

下面的代码示例包含三个代码段:服务器组件、订单类和客户端代码。The following code example includes three pieces of code: a server component, an order class, and client code. XSD.exe 实用工具可以使用 order 类生成服务器在传入消息内识别的架构。The order class can be used by the XSD.exe utility to generate schema that the server recognizes within incoming messages. 架构是一种 XML 格式的文件,用于描述类的 "形状"。The schema is an XML formatted file that describes the "shape" of the class. 然后,可以在客户端上使用此架构来生成客户端特定的 order 类,该类共享与服务器类相同的架构。This schema can then be used on the client side to generate a client-specific order class that shares the same schema as the server class.

下面的代码示例表示一个服务器组件,该组件通过消息队列接收订单。The following code example represents a server component that receives orders through a message queue. 消息的正文应为顺序对象,其架构与下面的 Order.cs 类相匹配。The body of the message should be an order object whose schema matches the Order.cs class below. 服务器进程或应用程序反序列化订单。The server process or application deserializes the 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 类,它为服务器上的应用程序接收和反序列化的顺序对象提供架构。The following code example represents the order class that provides a schema for the order objects that the application on the server receives and deserializes.

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

与服务器上的应用程序交互的任何客户端应用程序都必须通过将本地定义的 order 类中的信息序列化到消息正文中来向服务器发送消息。Any client application that interacts with the application on the server must send messages to the server by serializing information in a locally defined order class into the message body. 本地定义的 order 类必须与服务器定义的 order 类具有相同的架构,服务器上的应用程序将尝试对消息正文进行反序列化。The locally defined order class must have the same schema as the server-defined order class into which the application on the server will attempt to deserialize the message body. XSD.exe 实用程序允许服务器上的应用程序管理器创建和分发客户端必须用于将消息序列化到服务器的架构。The XSD.exe utility lets the manager of the application on the server create and distribute the schema the client must use to serialize messages going to the server.

当客户端应用程序的管理器接收订单类的架构时,将再次使用 XSD.exe 实用程序从架构生成客户端特定的 order 类。When the manager of the client application receives the schema for the order class, the XSD.exe utility is used again to generate a client-specific order class from the schema. 下面是在下面的客户端代码示例中使用的类,而不是服务器的 order 类 (XSD.exe 实用工具使架构生成的类与原始类) 的名称相同。It is this class that is used in the client code example below, not the server's order class (the XSD.exe utility causes the schema-generated class to have the same name as the original class). 此新 order 类用于将订单序列化为消息正文。This new order class is used to serialize the order into the message body.

下面的代码示例是客户端处理,用于序列化订单并将与订单关联的信息发送到队列。The following code example is the client-side processing, used to serialize an order and send the information associated with the order to a queue. 该代码将项、数量和地址信息与 XSD.exe 实用程序为 Order.cs 类生成的架构的元素相关联。The code associates Item, Quantity, and Address information with elements of the schema that were generated for the Order.cs class by the XSD.exe utility. 订单将发送到本地计算机上的 Orders 队列。An order is sent to the Orders queue on the local computer.

#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 类生成架构后,可以修改类。After the schema is generated from the order class on the server, you can modify the class. 除非架构发生更改,否则无需重新发布架构。Unless the schema changes, you do not need to redistribute the schema. 在您分配了架构并生成了客户端订单类之后,只要未修改架构本身,也可以独立于服务器的 order 类修改该客户端类。After you have distributed the schema and generated a client-side order class, that client class can also be modified independently of the server's order class, as long as the schema itself is not modified. 这两个类已变得松散耦合。The two classes have become loosely coupled.

注解

XmlMessageFormatter是的实例使用的默认格式化程序, MessageQueue 用于序列化写入队列的消息。The XmlMessageFormatter is the default formatter that an instance of MessageQueue uses to serialize messages written to the queue. 当你创建的实例时 MessageQueueXmlMessageFormatter 将为你创建一个实例,并将其与关联 MessageQueueWhen you create an instance of MessageQueue, an instance of XmlMessageFormatter is created for you and associated with the MessageQueue. 可以通过在代码中创建并将其分配给的属性,来指定不同的格式化程序 Formatter MessageQueueYou can specify a different formatter by creating it in your code and assigning it to the Formatter property of your MessageQueue.

队列的默认 XmlMessageFormatter 实例可以用于写入队列,但在 TargetTypes 格式化程序上设置或属性之前,不能使用它从队列中读取 TargetTypeNamesA queue's default XmlMessageFormatter instance can be used to write to the queue, but it cannot be used to read from the queue until you set either the TargetTypes or TargetTypeNames property on the formatter. 您可以在默认格式化程序实例上设置这两个值中的一个或两个值,也可以创建格式化程序的新实例,并通过将这些值作为参数传递到相应的构造函数来自动设置这些值 XmlMessageFormatterYou can either set one or both of these values on the default formatter instance, or you can create a new instance of the formatter and set the values automatically by passing them as arguments into the appropriate XmlMessageFormatter constructor.

当指定 TargetTypes 而不是时 TargetTypeNames ,将在编译时(而不是读取时间)检查类型存在,从而降低错误的可能性。When specifying TargetTypes rather than TargetTypeNames, type existence is checked at compile time rather than read time, reducing possibility for error. TargetTypeNames 要求每个项都是完全限定的,并指定其程序集名称。TargetTypeNames requires every entry to be fully qualified, specifying its assembly name. 此外,在使用多个并发版本时,还必须将版本号附加到目标类型名称。Further, when working with multiple concurrent versions, the version number must also be appended to the target type name as well.

TargetTypeNamesTargetTypes 属性告诉格式化程序在反序列化消息时要尝试匹配的架构。The TargetTypeNames and TargetTypes properties tell the formatter what schemas to attempt to match when deserializing a message. 这允许格式化程序解释消息正文。This allows the formatter to interpret the message body.

在消息正文中序列化的实例必须符合类型数组中表示的架构之一。The instance serialized in the message body must comply with one of the schemas represented in the type array. 使用方法读取消息时 Receive ,方法会创建一个类型为的对象,该对象对应于标识的架构并将消息正文读入其中。When you read the message using the Receive method, the method creates an object of the type that corresponds to the schema identified and reads the message body into it.

从队列中读取时,只需设置这两个属性中的一个,但可以同时设置这两个属性。Only one of the two properties needs to be set when reading from the queue, but you can set both. 类型集是这两个属性的组合集。The set of types is the combined set from the two properties. 要使用哪个属性取决于您的应用程序。The decision of which property to use is specific to your application. 如果消息正文包含一个类型,该类型的架构与任一属性的数组中的任何类型都不匹配,则在读取消息时将引发异常。If the message body contains a type whose schema does not match any of the types in the array for either property, an exception will be thrown when the message is read.

XmlMessageFormatter是松散耦合的基于 XML 的消息传递的重要组成部分。The XmlMessageFormatter is a crucial component of loosely coupled XML-based messaging. XSD.exe 实用工具使用 XML 格式来生成 XML 架构,例如在使用实用工具序列化应用程序所使用的类时。The XSD.exe utility uses the XML format is used to generate XML schema, such as when you use the utility to serialize a class used by your application. 类必须具有一个无参数的构造函数。The class must have a parameterless constructor.

当实用工具基于您分发的用于描述类数据的架构生成类时,将在反向处理中再次使用该格式。The format is used again in the reverse process when the utility generates a class based on the schema you distribute to describe your class data. 使用实用工具和它生成的 XML 架构,你可以避免在类的实现已更改之后每次重新编译类时 redistributing.dll 文件。The use of the utility and the XML schema it generates enables you to avoid redistributing.dll files every time you recompile a class after the implementation of your class has changed. 只要该架构在客户端或服务器上不会更改,任何一侧的其他更改也不会影响另一方。As long as the schema does not change on the client or the server, other changes on either side do not affect the other.

构造函数

XmlMessageFormatter()

初始化 XmlMessageFormatter 类的新实例但不设置目标类型。Initializes a new instance of the XmlMessageFormatter class, without target types set.

XmlMessageFormatter(String[])

初始化 XmlMessageFormatter 类的新实例,并将传入的目标类型设置为(完全限定)字符串值数组。Initializes a new instance of the XmlMessageFormatter class, setting target types passed in as an array of (fully qualified) string values.

XmlMessageFormatter(Type[])

初始化 XmlMessageFormatter 类的新实例,并将传入的目标类型设置为对象类型的数组。Initializes a new instance of the XmlMessageFormatter class, setting target types passed in as an array of object types.

属性

TargetTypeNames

指定可能的类型集,这些类型将由格式化程序从提供的消息进行反序列化。Specifies the set of possible types that will be deserialized by the formatter from the message provided.

TargetTypes

指定可能的类型集,这些类型将由格式化程序从提供的消息进行反序列化。Specifies the set of possible types that will be deserialized by the formatter from the message provided.

方法

CanRead(Message)

确定格式化程序是否可以反序列化消息。Determines whether the formatter can deserialize the message.

Clone()

创建 XmlMessageFormatter 类的实例,此实例的读/写属性(目标类型集)与当前 XmlMessageFormatter 实例相同。Creates an instance of the XmlMessageFormatter class whose read/write properties (the sets of target types) are the same as the current XmlMessageFormatter instance.

Equals(Object)

确定指定对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(继承自 Object)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
Read(Message)

从给定的消息中读取内容,并创建包含反序列化消息的对象。Reads the contents from the given message and creates an object that contains the deserialized message.

ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

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

将对象序列化为消息体。Serializes an object into the body of the message.

适用于

另请参阅