使用KB2901983破坏类XmlWriterBackedStream中的更改

时间:2015-01-21 13:54:30

标签: .net web-services wcf

我有一个针对.NET Framework 4.0的应用程序,昨天我们的客户进行了某种更新,我们的应用程序停止了工作。在深入研究.NET Framework源代码之后,我在XmlWriterBackedStream类中找到了原因。我机器上的代码如下:


// C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.ServiceModel.Web\v4.0_4.0.0.0__31bf3856ad364e35\System.ServiceModel.Web.dll
// System.ServiceModel.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

// Architecture: AnyCPU (64-bit preferred)
// Runtime: .NET 4.0

// System.ServiceModel.Channels.StreamBodyWriter.XmlWriterBackedStream
public override void Write(byte[] buffer, int offset, int count)
{
    if (this.writer.WriteState == WriteState.Start)
    {
        this.writer.WriteStartElement("Binary", string.Empty);
        this.writer.WriteBase64(buffer, offset, count);
        return;
    }
    if (this.writer.WriteState == WriteState.Content)
    {
        this.writer.WriteBase64(buffer, offset, count);
    }
}

而客户机器上的.NET 4.0 Framework代码如下所示:


// C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.ServiceModel.Web\v4.0_4.0.0.0__31bf3856ad364e35\System.ServiceModel.Web.dll
// System.ServiceModel.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

// Architecture: AnyCPU (64-bit preferred)
// Runtime: .NET 4.0

// System.ServiceModel.Channels.StreamBodyWriter.XmlWriterBackedStream
public override void Write(byte[] buffer, int offset, int count)
{
    if (this.writer.WriteState == WriteState.Content || this.isQuirkedTo40Behavior)
    {
        this.writer.WriteBase64(buffer, offset, count);
        return;
    }
    if (this.writer.WriteState == WriteState.Start)
    {
        this.writer.WriteStartElement("Binary", string.Empty);
        this.writer.WriteBase64(buffer, offset, count);
    }
}

请注意cutomers机器上的this.isQuirkedTo40Behavior。这迫使我针对.NET Framework 4.5编译应用程序,以使其再次运行。

这是.NET Framework中的错误吗?如何在不针对4.5框架的情况下让我的应用再次运行?

这是我的班级引起的问题:


class MyMessageWriter : StreamBodyWriter
{
   private readonly Action<System.IO.Stream> writerAction;

   public MyMessageWriter(Action<System.IO.Stream> writer) : base(false)
   {
      this.writerAction = writer;
   }

   protected override void OnWriteBodyContents(System.IO.Stream stream)
   {
      this.writerAction(stream);
   }
}

1 个答案:

答案 0 :(得分:3)

这似乎是一个突破性的变化,随着KB2901983的安装(感谢微软!)。但是,我找到了解决此问题的方法,因此您仍然可以将应用程序定位到.NET Framework 4.0(有点难看 - 但它有效):


class MyMessageWriter : StreamBodyWriter
{
   private readonly Action<System.IO.Stream> writerAction;

   public MyMessageWriter(Action<System.IO.Stream> writer) : base(false)
   {
      this.writerAction = writer;
   }

   protected override void OnWriteBodyContents(System.IO.Stream stream)
   {
      this.writerAction(stream);
   }

   protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
   {
      writer.WriteStartElement("Binary", string.Empty);
      writer.WriteBase64(new byte[0], 0, 0); // force WriteState.Content

      base.OnWriteBodyContents(writer);
   }
}

<强>更新

如果您没有安装KB2901983,此解决方案似乎无效。

更新2

我必须添加writer.WriteBase64(new byte[0], 0, 0)以强制XmlDictionaryWriter的状态为WriteState.Content现在它应该在安装KB2901983之前和之后工作

更新3

另一种解决方案是将XmlDictionaryWriter包装到您自己的Stream派生类