2012-06-26 2 views
2

Я бил головой об этом, чтобы воспользоваться. Любые идеи приветствуются!Msmq и sgen для полной ошибки xmlserialization

У меня есть приложение client/listener в vb.net с использованием MSMQ, и он работает на 100% отлично, когда я не использую sgen.exe для генерации сериализаций во время компиляции.

При использовании sgen он не работает на части слушателя.

 qOrders.Formatter = New XmlMessageFormatter(New Type() {GetType(InfoMessage)}) 

     m = qOrders.EndReceive(e.AsyncResult) 

Это бомбы на м. m.Body имеет ошибку "Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.", а остальные свойства также имеют ошибки, не получающие значение.

Сборка прочная, и приложение App.XmlSerializers.dll также подписано правильно. Я знаю, что dll используется, потому что я не могу удалить его во время работы программы.

Класс InfoMessage - это простой публичный класс с 3 общедоступными членами строки. Проверяя dll с Reflector, я вижу, что sgen создал класс InfoMessageSerializer.

Проблема не на стороне клиента, потому что я удаляю dll и запускаю прослушиватель, он работает как обычно.

Итак, что может быть неправильным здесь? : О

Спасибо,

Джон

Edit: Ссылка на источник Слушатель: http://pastebin.com/TqWfLVJ0

ответ

1

Существует design limitation из sgen продукции. Это ограничение было never removed:

Эти сгенерированные сборки не могут использоваться на стороне сервера веб-службы. Этот инструмент предназначен только для клиентов веб-служб и сценариев ручной сериализации.

В принципе, вы не ожидали запустить sgen сделать на стороне сервера веб-сервиса быстрее, потому что XmlSerializer время запуска не является решающим фактором его производительности (в отличие от некоторых типов клиентов).

Конечно, sgenможет использоваться на стороне сервера в сценарии не-веб-службы, до тех пор, пока вы не пропустить ни XmlAttributeOverrides конструктору XmlSerializer.

С MSMQ, есть выбор бинарной и XML-сериализации, и ваш код выбирает последний здесь:

qOrders.Formatter = New XmlMessageFormatter(New Type() {GetType(InfoMessage)}) 

Итак, давайте посмотрим, как MessageQueue создает XmlSerializer. Ниже приведен метод XmlMessageFormatter, взятый из System.Messaging.dll, .NET 4.0. Совместимость с .NET 2.0 аналогична.

private void CreateTargetSerializerTable() 
{ 
    if (!this.typeNamesAdded) 
    { 
    for (int index = 0; index < this.targetTypeNames.Length; ++index) 
    { 
     Type type = Type.GetType(this.targetTypeNames[index], true); 
     if (type != (Type) null) 
     this.targetSerializerTable[(object) type] 
      = (object)new XmlSerializer(type); 
    } 
    this.typeNamesAdded = true; 
    } 
    if (!this.typesAdded) 
    { 
    for (int index = 0; index < this.targetTypes.Length; ++index) 
     this.targetSerializerTable[(object) this.targetTypes[index]] 
     = (object)new XmlSerializer(this.targetTypes[index]); 
    this.typesAdded = true; 
    } 
    if (this.targetSerializerTable.Count == 0) 
    throw new InvalidOperationException(Res.GetString("TypeListMissing")); 
} 

Как вы можете видеть, MSMQ не поставляет XmlAttributeOverrides, в отличие от сервера веб-службы кода на стороне в рамках. Тем не менее, есть и другие люди, которые have trouble с объединением XmlMessageFormatter и sgen.

Я думаю, что sgen все еще может быть сделано для работы с MSMQ, потому что MSMQ не использует XmlAttributeOverrides, но вы должны убедиться, что вы не используете опцию proxytypes командной строки, и что вы по-прежнему движется путь за пределами от того, что Microsoft когда-либо тестировала.

Я бы советовал смотреть на эти возможности:

  • Избегайте использования sgen с MSMQ.
  • Избегайте использования опции /proxytypes с sgen.
  • Отключить SGenUseProxyTypes в случае, если вы вызываете sgen из вашего файла проекта (look here, чтобы посмотреть, как).
  • Посмотрите на использование двоичной сериализации с помощью MSMQ.
  • Обратите внимание на то, какие типы вы отправляете через очередь на стороне клиента.
+0

Интересно! Один вопрос: оба документа обсуждают веб-службы - и я ничего не делаю с веб-службой, так как это применимо? Фактически, это просто гоночный PoC для связи MSMQ (уменьшенный от фактического приложения, чтобы выявить проблему). – johnjohn

+0

@johnjohn - Ответ расширен. Кстати, если ваш вопрос содержит больше кода, особенно, кто и как создает экземпляр 'XmlSerializer', что сделало бы его лучшим вопросом. –

+0

Спасибо за разъяснение. Я обновил ссылку на код Listener - он бомбит метод qOrders_ReceiveCompleted (который содержит код в вопросе). Он вообще не использует XmlAttributeOverrides. – johnjohn

Смежные вопросы