XmlMessageFormatter Класс

Определение

Сериализует объекты в текст сообщения или десериализует текст сообщения в объекты, используя для этого формат XML, основанный на определении схемы XSD.

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, схема которого соответствует приведенному ниже классу Order.cs. Серверный процесс или приложение десериализует заказ.

#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, предоставляющий схему для объектов порядка, которые приложение на сервере получает и десериализует.

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 позволяет руководителю приложения на сервере создавать и распространять схему, используемую клиентом для сериализации сообщений, поступающих на сервер.

Когда диспетчер клиентского приложения получает схему для класса order, служебная программа XSD.exe снова используется для создания класса заказов для конкретного клиента из схемы. Именно этот класс используется в приведенном ниже примере клиентского кода, а не в классе порядка сервера (служебная программа XSD.exe приводит к тому, что созданный схемой класс имеет то же имя, что и исходный класс). Этот новый класс порядка используется для сериализации порядка в тексте сообщения.

В следующем примере кода показана обработка на стороне клиента, используемая для сериализации заказа и отправки сведений, связанных с заказом, в очередь. Код связывает сведения Item, Quantity и Address с элементами схемы, которые были созданы для класса Order.cs служебной программой XSD.exe. Заказ отправляется в очередь "Заказы" на локальном компьютере.

#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 на сервере можно изменить класс . Если схема не изменится, повторно распространять схему не нужно. После распространения схемы и создания класса порядка на стороне клиента этот клиентский класс также можно изменить независимо от класса порядка сервера, если сама схема не будет изменена. Эти два класса стали слабо связаны.

Комментарии

XmlMessageFormatter это модуль форматирования по умолчанию, используемый MessageQueue экземпляром для сериализации сообщений, записанных в очередь. При создании экземпляра MessageQueueсоздается экземпляр , связанный XmlMessageFormatter с MessageQueue. Вы можете указать другой модуль форматирования, создав его в коде и назначив его свойству Formatter объекта MessageQueue.

Экземпляр очереди по умолчанию XmlMessageFormatter можно использовать для записи в очередь, но его нельзя использовать для чтения из очереди, пока вы не задаете TargetTypes свойство или TargetTypeNames для модуля форматирования. Можно задать одно или оба этих значения в экземпляре модуля форматирования по умолчанию или создать новый экземпляр модуля форматирования и задать значения автоматически, передав их в качестве аргументов в соответствующий XmlMessageFormatter конструктор.

При указании TargetTypes вместо TargetTypeNames, существование типа проверяется во время компиляции, а не во время чтения, что снижает вероятность возникновения ошибок. TargetTypeNames требует, чтобы каждая запись была полной, указывая имя сборки. Кроме того, при работе с несколькими параллельными версиями номер версии также должен быть добавлен к имени целевого типа.

Свойства TargetTypeNames и TargetTypes сообщают модульу форматирования, какие схемы следует пытаться сопоставить при десериализации сообщения. Это позволяет форматировщику интерпретировать текст сообщения.

Экземпляр, сериализованный в тексте сообщения, должен соответствовать одной из схем, представленных в массиве типов. При чтении сообщения с помощью 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)

Сериализует объект в текст сообщения.

Применяется к

См. также раздел