如何将 com 或 excel 对象序列化为二进制格式,以便我可以将其存储在 asp.net 的内存流中
这是示例代码...但我收到了序列化异常。
xlbook 是对象,我想将此对象保存到内存流。
unsafe public void Save(IStream stream, bool clearDirty, Excel.Workbook xlbook)
{
try
{
//if (stream == null)
//{
// return;
//}
//object data = xlbook;
if (xlbook == null)
{
return;
}
// convert data to byteArray
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
//AppDomain currentDomain = AppDomain.CurrentDomain;
//currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
//here im getting exception.
binaryFormatter.Serialize(memoryStream, xlbook);
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
//get memory pointer
int cb;
int* pcb = &cb;
//save data
byte[] arrayLen = BitConverter.GetBytes(bytes.Length);
stream.Write(arrayLen, arrayLen.Length, new IntPtr(pcb));
stream.Write(bytes, bytes.Length, new IntPtr(pcb));
//currentDomain.AssemblyResolve -= new ResolveEventHandler(currentDomain_AssemblyResolve);
}
catch
{
}
}
我得到的例外是...
在程序集“Microsoft.Office.Interop.Excel,Version=11.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c”中键入“Microsoft.Office.Interop.Excel.WorkbookClass”未标记为可序列化。
Here is the sample code...but i am getting the serializationException.
xlbook is the object and i want to save this object to memorystream.
unsafe public void Save(IStream stream, bool clearDirty, Excel.Workbook xlbook)
{
try
{
//if (stream == null)
//{
// return;
//}
//object data = xlbook;
if (xlbook == null)
{
return;
}
// convert data to byteArray
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
//AppDomain currentDomain = AppDomain.CurrentDomain;
//currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
//here im getting exception.
binaryFormatter.Serialize(memoryStream, xlbook);
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
//get memory pointer
int cb;
int* pcb = &cb;
//save data
byte[] arrayLen = BitConverter.GetBytes(bytes.Length);
stream.Write(arrayLen, arrayLen.Length, new IntPtr(pcb));
stream.Write(bytes, bytes.Length, new IntPtr(pcb));
//currentDomain.AssemblyResolve -= new ResolveEventHandler(currentDomain_AssemblyResolve);
}
catch
{
}
}
exception i am getting is...
Type 'Microsoft.Office.Interop.Excel.WorkbookClass' in Assembly 'Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' is not marked as serializable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了使 .Net 序列化器正常工作,要序列化的对象必须具有标记为可序列化的类型。在这种情况下,WorkbookClass 没有这样标记。您可以通过为 WorkbookClass 制作包装器并实现 ISerialized 来解决这个问题,或者您可以制作格式化程序/格式化代理来为您完成这项工作。但你采取的任何解决方案都注定会失败。
为什么?首先COM对象的内部结构是未知的,只知道它的接口。他们大多是无人管理的。 .Net 只是在其上放置了一个漂亮的包装器。因此,当简单地将其所有字节写入流时,您可能(阅读:将)序列化非托管指针。当再次反序列化它们时,它们将不会指向任何内容或错误的内容。由于它们是非托管的,因此无法确定它们是指针(而不是数据),也无法确定它们指向什么。 (或者你必须深入挖掘并在运行时弄清楚它的二进制格式。)另外,根据我对 Office COM 对象的记忆,它们大多会生成自己的 Office 进程,并与之通信,所以你甚至可能最终序列化进程的句柄。总而言之,注定会失败。
可能 WorkbookClass (或其父级/容器)有一个类似 .Save() 的方法,您应该使用它并使用 FileStream 来保存数据。
For the .Net serializer to work, the objects it is to serialize must have a type marked serializable. In this case the WorkbookClass is not marked as such. You can probably get aroud this by either making a wrapper for the WorkbookClass and implement the ISerializable, or you can make a formatter/formatting surogates to do the work for you. But any solution you take is bound to fail.
Why? First of all the COM objects internal structure is not known, only it's interface. They are mostly unmanaged. .Net simply puts a nice wrapper on top of it. So when simply writing all its bytes to a stream, you might (read: will) serialize unmanaged pointers. When deserializing them again, they will not point to anything, or to something wrong. And since they are unmanaged, there is no way to figure out that they are pointers (and not data), nor what they point to. (Or you would have to dig very deep and figure out its binary format at runtime.) Also from what I remember of the office COM objects, they will mostly spawn their own office process, and communicate with that, so you could even end up serializing a handle to a process. All in all, bound to fail.
Probably the WorkbookClass (or it's parent/container) has a .Save()-like method, you should use that and use a FileStream to wherever you saved the data.