首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BinaryFormatter in .netcore

BinaryFormatter in .netcore
EN

Stack Overflow用户
提问于 2019-09-20 11:47:42
回答 1查看 1.5K关注 0票数 1

BinaryFormatter框架和.NET核心2.2中的.NET兼容性问题

我们已经使用byte[] Framework4.0类库(多个项目的公共库)中的BinaryFormatter将BinaryFormatter转换为DataSet的现有代码。现在,我们添加了一个新的asp.net核心2.2项目,并尝试使用相同的现有库,幸运的是,我们解决了所有的dll问题,但无法调用BinaryFormatter反序列化方法。

以下是通用代码:

代码语言:javascript
复制
        BinaryFormatter oBinaryFormatter = new BinaryFormatter();

        using (MemoryStream oMemoryStream = new MemoryStream())
        {
            //Deserialize the byte array into a DataSet and return it to the caller
            oMemoryStream.Write(abData, 0, abData.Length);
            oMemoryStream.Position = 0;
            return (T)(oBinaryFormatter.Deserialize(oMemoryStream));
        }
代码语言:javascript
复制
Inner Exception: 
      Type 'System.String' is not deserializable.
Source:
      System.Private.CoreLib

Stack Trace:
         at System.UnitySerializationHolder.GetRealObject(StreamingContext context)
   at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)
   at System.Runtime.Serialization.ObjectManager.DoFixups()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(BinaryParser serParser, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, Boolean check)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at System.Data.DataSet.DeserializeDataSetSchema(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat, SchemaSerializationMode schemaSerializationMode)
   at System.Data.DataSet..ctor(SerializationInfo info, StreamingContext context, Boolean ConstructSchema)
   at System.Data.DataSet..ctor(SerializationInfo info, StreamingContext context)
EN

回答 1

Stack Overflow用户

发布于 2019-09-20 15:57:53

我无法重现这个代码的问题:

代码语言:javascript
复制
var ds=new DataSet();
var table=new DataTable("Moo");
table.Columns.Add("Field1",typeof(string));
table.Columns.Add("Field2",typeof(int));

table.Rows.Add("Value1",1);
ds.Tables.Add(table);
ds.AcceptChanges();
var bf = new BinaryFormatter();

using (var stream=File.OpenWrite("test.bin"))
{
    bf.Serialize(stream,ds);
}

using (var stream2=File.OpenRead("test.bin"))
{
    var ds2=(DataSet)bf.Deserialize(stream2);

    Debug.Assert(ds.Tables[0].TableName==ds2.Tables[0].TableName);
    Debug.Assert(ds.Tables[0].Rows.Count==ds2.Tables[0].Rows.Count);
    Debug.Assert((string)ds2.Tables[0].Rows[0]["Field1"]=="Value1");
    Debug.Assert((int)ds2.Tables[0].Rows[0]["Field2"]==1);

}

查看生成的文件显示包含dataset的模式和XML加上类型元数据,使其比单独的XML文件更冗长:

代码语言:javascript
复制
              NSystem.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089   System.Data.DataSet   DataSet.RemotingVersion   XmlSchemaXmlDiffGramSystem.Version            <?xml version="1.0" encoding="utf-16"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Moo">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Field1" type="xs:string" msdata:targetNamespace="" minOccurs="0" />
              <xs:element name="Field2" type="xs:int" msdata:targetNamespace="" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>   ‚<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"><NewDataSet><Moo diffgr:id="Moo1" msdata:rowOrder="0"><Field1>Value1</Field1><Field2>1</Field2></Moo></NewDataSet></diffgr:diffgram>   System.Version   _Major_Minor_Build    _Revision           sion           

这是1.3KB,用于保存文本的99字节。使用GZipStream编写相同的代码将产生82个字节:

代码语言:javascript
复制
using(var gs=new GZipStream(File.OpenWrite("text.gz"),CompressionMode.Compress))
{
    ds.WriteXml(gs);
}

但是,在.NET 4.x中创建一个文件并在.NET核心中读取它还不起作用。甚至还有一个尚未修复的关于这个的Github问题

由于安全性和兼容性问题而使用不鼓励BinaryFormatter。该类可以根据文件的内容反序列化任何内容,包括意外类型或恶意类型。这也是导致这个兼容性问题的原因-反序列化器产生了一个与.NET核心运行时类型不匹配的新.NET。

还有更多的普通问题--添加或删除属性可能会导致兼容性问题,因为BinaryFormatter创建的类型与应用程序其余部分使用的类型不匹配。这个问题在版本容忍度序列化中有描述。

我不会屏住呼吸等待跨框架的修复。这种类型是不受欢迎的,积极的气馁和很少使用,这意味着将有很少的志愿者来修复它。同时,核心团队员工有更高优先级的问题,如gRPC和稳定流行的堆栈(如WinForms和WPF )。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58027786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档