我有一个针对.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);
}
}
答案 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派生类
中