C# 反序列化与序列化时不同的对象

C# 反序列化与序列化时不同的对象,c#,asp.net,C#,Asp.net,我对反序列化对象有问题。我收到一个错误“System.Int32”无法转换为类型“System.Decimal”。此对象有许多子对象,由于此对象已序列化,因此新版本的对象有一个或多个字段已从int更改为decimal,现在我无法反序列化该对象,因为它与原始对象不匹配 我尝试过使用OnDeserialization方法,但上下文参数根本帮不了我 有办法解决这个问题吗?我在网上找到了一些例子,但并不适用于我的情况。我只想知道是否有一种方法可以查看序列化对象,即使我的对象现在已经更改,或者是否有一种方

我对反序列化对象有问题。我收到一个错误“System.Int32”无法转换为类型“System.Decimal”。此对象有许多子对象,由于此对象已序列化,因此新版本的对象有一个或多个字段已从int更改为decimal,现在我无法反序列化该对象,因为它与原始对象不匹配

我尝试过使用OnDeserialization方法,但上下文参数根本帮不了我

有办法解决这个问题吗?我在网上找到了一些例子,但并不适用于我的情况。我只想知道是否有一种方法可以查看序列化对象,即使我的对象现在已经更改,或者是否有一种方法可以找出哪些变量需要更改为十进制,以及如何执行

谢谢

嗨,乔尔,
我已经添加了你的代码,但我不太确定如何从我的代码中调用它。以下是我得到的:

public static Application LoadSnapshot(int appID, int statusID)
{  
  ApplicationSnapshotCollection AppSnap = new ApplicationSnapshotCollection();
  AppSnap.LoadByAppAndSnapshotStatusID(appID, statusID);
  Application app = null;

  try
  {
    if (AppSnap.Count > 0)
    {
      if (AppSnap[0].Snapshot != null)
      {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream((byte[])AppSnap[0].Snapshot);
        ms.Position = 0;
        app = (Application)bf.Deserialize(ms);

        ms.Close();

        return app;
      }
      return null;
    }

    return null;

  }
  catch (Exception ex)
  {
    Dfait.Diagnostics.LogWriter.CriticalError(ex);
    return null;
  }

}

[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
  //What do I put here?


}

protected Application(SerializationInfo info, StreamingContext context) 
{
  SerializationInfoEnumerator e = info.GetEnumerator();     
  Console.WriteLine("Values in the SerializationInfo:");     
  while (e.MoveNext())     
  {
    Console.WriteLine("Name={0}, ObjectType={1}, Value={2}", e.Name, e.ObjectType,   e.Value);     
  } 
}  
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) 
{  

} 

在我的场景中,如何使用正确的参数调用构造函数?

您说您已经尝试使用OnDeserialization方法,听起来您可以访问StreamingContext,因此听起来您正在Vistual Studio调试器中逐步执行,并且您可以访问源代码。您可以在类上实现
ISerializable
接口,这将使您能够更好地控制反序列化过程。实现
ISerializable
接口有两个步骤,第一个步骤是添加一个构造函数,该构造函数将
SerializationInfo
StreamingContext
作为参数。从那里,您可以通过调用
SerializationInfo
实例上的
GetEnumerator
方法来迭代类上的序列化属性

实现
ISerializable
的第二部分是定义方法
void ISerializable.GetObjectData(SerializationInfo,StreamingContext上下文)
。在您的情况下,除了定义它之外,您不需要做任何事情来防止编译器抱怨

编辑:我在代码示例中添加了类声明,以显示如何添加ISerializable接口

public class Application : ApplicationBase, ISerializable
{
    protected Application(SerializationInfo info, StreamingContext context)
    {
        SerializationInfoEnumerator e = info.GetEnumerator();
        Console.WriteLine("Values in the SerializationInfo:");
        while (e.MoveNext())
        {
            Console.WriteLine("Name={0}, ObjectType={1}, Value={2}", e.Name, e.ObjectType, e.Value);
        }
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {

    }
}

您说您已经尝试使用OnDeserialization方法,听起来您可以访问StreamingContext,因此听起来您正在Vistual Studio调试器中单步执行,并且可以访问源代码。您可以在类上实现
ISerializable
接口,这将使您能够更好地控制反序列化过程。实现
ISerializable
接口有两个步骤,第一个步骤是添加一个构造函数,该构造函数将
SerializationInfo
StreamingContext
作为参数。从那里,您可以通过调用
SerializationInfo
实例上的
GetEnumerator
方法来迭代类上的序列化属性

实现
ISerializable
的第二部分是定义方法
void ISerializable.GetObjectData(SerializationInfo,StreamingContext上下文)
。在您的情况下,除了定义它之外,您不需要做任何事情来防止编译器抱怨

编辑:我在代码示例中添加了类声明,以显示如何添加ISerializable接口

public class Application : ApplicationBase, ISerializable
{
    protected Application(SerializationInfo info, StreamingContext context)
    {
        SerializationInfoEnumerator e = info.GetEnumerator();
        Console.WriteLine("Values in the SerializationInfo:");
        while (e.MoveNext())
        {
            Console.WriteLine("Name={0}, ObjectType={1}, Value={2}", e.Name, e.ObjectType, e.Value);
        }
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {

    }
}

序列化时它是如何修改的?您是在寻找当前问题的解决方案,还是关于如何避免将来出现类似问题的建议?我正在使用BinaryFormatter进行序列化…我是这样做的:BinaryFormatter bf=new BinaryFormatter();MemoryStream ms=新的MemoryStream();bf.序列化(ms、app);pc[“@appID”].Value=app.appID;pc[“@App”].Value=ms.ToArray();pc[“@statusID”]。值=statusID;克洛斯女士()。。。然后我将其存储在数据库中。寻找解决当前问题的方法。通过将接口放入类声明中来实现接口,这样您的类将被定义为:public class Application:ISerializable如果它已经从基类继承,则将接口放在基类之后,由逗号分隔:public Application:ApplicationBase,ISerializable一旦类实现ISerializable,二进制格式化程序将在反序列化对象时查找与该签名匹配的构造函数,因此,您应该能够设置断点并调试当前代码。序列化时它是如何修改的?您是在寻找当前问题的解决方案,还是关于如何避免将来出现类似问题的建议?我正在使用BinaryFormatter来序列化…我是这样做的:BinaryFormatter bf=new BinaryFormatter();MemoryStream ms=新的MemoryStream();bf.序列化(ms、app);pc[“@appID”].Value=app.appID;pc[“@App”].Value=ms.ToArray();pc[“@statusID”]。值=statusID;克洛斯女士()。。。然后我将其存储在数据库中。寻找解决当前问题的方法。通过将接口放入类声明中来实现接口,这样您的类将被定义为:public class Application:ISerializable如果它已经从基类继承,则将接口放在基类之后,用逗号分隔:public Application:ApplicationBase,ISerializable一旦类实现ISerializable,二进制格式化程序将在反序列化对象时查找与该签名匹配的构造函数,因此您应该能够设置断点并调试当前代码。嗨,Joel,我的构造函数似乎从未被调用过。我添加了你的代码(见我的原始帖子…我添加了代码),但在“app=(Application)bf.Deserialize(ms);”行失败。它确实进入了OnDeserialization方法,但我不确定是否仍然需要它。我有权访问此方法中的上下文,但无权访问SerializationInfo。我做错了什么吗?您不应该仍然需要
[ondesellizing]
方法。事实上,它可能是国际性的