【问题标题】:Msmq and sgen for xmlserialization utter failure用于 xmlserialization 的 Msmq 和 sgen 彻底失败
【发布时间】:2012-06-26 21:45:15
【问题描述】:

我一直在努力解决这个问题。非常欢迎任何想法!

我在 vb.net 中有一个使用 MSMQ 的客户端/侦听器应用程序,当我不使用 sgen.exe 在编译时生成序列化时,它可以 100% 正常工作。

当使用 sgen 时,它在侦听器部分失败。

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

        m = qOrders.EndReceive(e.AsyncResult)

它会轰炸 m。 m.Body 有错误"Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.",其余属性也有没有接收到值的错误。

程序集具有强名称,并且 App.XmlSerializers.dll 也已正确签名。我知道这个 dll 被使用了,因为我无法在程序运行时删除它。

InfoMessage 类是一个简单的公共类,具有 3 个公共字符串成员。使用 Reflector 检查 dll,我确实看到 sgen 已经生成了一个 InfoMessageSerializer 类。

问题不在客户端,因为我删除了 dll 并运行了侦听器,它照常工作。

那么,这里有什么问题吗? :o

谢谢,

约翰

编辑:链接到监听器来源:http://pastebin.com/TqWfLVJ0

【问题讨论】:

    标签: .net vb.net xml-serialization msmq xmlserializer


    【解决方案1】:

    有一个design limitationsgen 输出。这个限制是never removed

    这些生成的程序集不能用于 Web 服务的服务器端。此工具仅适用于 Web 服务客户端和手动序列化场景。

    基本上,您不应该运行sgen 来使Web 服务的服务器端更快,因为XmlSerializer 启动时间并不是其性能的关键因素(与某些类型的客户端相比)。

    当然,sgen可以在非web服务的场景下用在服务器端,只要不向XmlSerializer的构造函数传递任何XmlAttributeOverrides即可。

    使用 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,这与框架中的 Web 服务服务器端代码不同。不过,还有其他人 have trouble 结合了 XmlMessageFormatter 和 sgen

    我的猜测是 sgen 仍然可以与 MSMQ 一起使用,因为 MSMQ 不使用 XmlAttributeOverrides,但是你必须确保你没有使用 proxytypes 命令行选项,并且你仍然在微软测试的范围之外。

    我建议考虑这些可能性:

    • 避免在 MSMQ 中使用 sgen
    • 避免将/proxytypes 选项与sgen 一起使用。
    • 禁用SGenUseProxyTypes,以防您从项目文件中调用sgenlook here 看看如何)。
    • 看看在 MSMQ 中使用二进制序列化。
    • 密切注意您通过客户端队列发送的类型。

    【讨论】:

    • 有趣!但是有一个问题:两份文档都讨论了 Web 服务——而我没有做任何与 Web 服务相关的事情,那么它是如何应用的呢?事实上,它只是一个用于 MSMQ 通信的简单 PoC(从实际应用缩小以查明问题)。
    • @johnjohn - 答案已扩展。顺便说一句,如果您的问题包含更多代码,尤其是谁以及如何实例化 XmlSerializer,那将是一个更好的问题。
    • 感谢您的澄清。我已经更新了监听器代码的链接 - 它在 qOrders_ReceiveCompleted 方法(其中包含问题中的代码)上爆炸。它根本不使用 XmlAttributeOverrides。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 2014-07-22
    • 2016-11-05
    • 2015-06-23
    • 2017-12-24
    • 1970-01-01
    相关资源
    最近更新 更多