【问题标题】:C# Cannot serialize object because MainViewModel is not marked SerializableC# 无法序列化对象,因为 MainViewModel 未标记为 Serializable
【发布时间】:2015-07-09 13:39:14
【问题描述】:

我刚开始玩一点二进制序列化。

我有一个要序列化的类“SerializeMe”:

[Serializable]
public class ViewModelBase : INotifyPropertyChanged
{
    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void RaisePropertyChanged(
                      [CallerMemberName]string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

[Serializable]
public class SerializeBase : ViewModelBase
{
  .
  .
  .
}

我要序列化的类:

[Serializable]
public class SerializeMe : SerializeBase 
{
     .
     .
     .
}

在我的 MainViewModel 中,我有一个“SerializeBase”类型的 ObservableCollection 和一个序列化集合中第一项的方法:

public class MainViewModel : ViewModelBase
{
   private ObservableCollection<SerializeBase> _workspaces;

   public MainViewModel()
   {
      _workspaces = new ObservableCollection<SerializeBase>
   // EDIT
                    {
                         new SerializeMe(),
                         new SerializeMe()
                    }
   // EDIT END
   }

   public ObservableCollection<SerializeBase> Workspaces
   {
         get { return _workspaces; }
         set
         {
               if (value == _workspaces)
                   return;

               _workspaces = value;
               RaisePropertyChanged();
         }
   }

   public void SerializeFirst()
   {
        var fisrtItem = _workspaces.FirstOrDefault();
        if (firstItem == null)
            return;

        using(var stream = new FileStream("file.bin", FileMode.Create))
        {
            new BinaryFormatter().Serialize(stream, firstItem);
        }
   }
}

只要我将 MainViewModel 标记为可序列化,所有这些都有效。

这行得通:

namespace Namespace
{
   [Serializable]
   public class MainViewModel : ViewModelBase
   .
   .
   .

这不是:

namespace Namespace
{
   public class MainViewModel : ViewModelBase
   .
   .
   .

错误详情:MainViewModel... 类型未标记为可序列化。

有人可以解释为什么我的 MainViewModel 必须是可序列化的吗?没看懂。

谢谢。

【问题讨论】:

  • 父类是可序列化的并不意味着子类是可序列化的。您必须明确告诉它它可以被序列化,否则它假定它不能。至少[Serializable] 属性是这样工作的。如果你在基类上实现了ISerializable,那么我认为它可以工作。
  • 感谢您的回答,但是:我不想序列化我的 MainViewModel。只有 _workspaces 集合中的第一项
  • 您可能想澄清您的问题,因为Workspaces 不包含MainViewModel 引用并不明显,因为它派生自一个公共基类,它似乎肯定可以。跨度>
  • 完全题外话——为什么要序列化视图模型?
  • 不确定我是否理解您的评论。工作区不能引用 MainViewModel,MainViewModel 派生自 ViewModelBase 而不是 SerializeBase

标签: c# wpf serialization mvvm


【解决方案1】:

我最近在尝试序列化大型数据集时遇到了这个确切的问题。

问题在于,您的某个模型以某种方式结束了您正在使用的视图模型\命令\转换器中的某个元素的链接,因此序列化程序认为它需要序列化整个视图模型。

如果您确实将主视图模型标记为可序列化,它将开始遍历所有其他视图模型和连接到您的主视图模型的命令,并给您带来同样的问题。

您需要找出连接的原因和连接位置,然后阻止它发生。

【讨论】:

    【解决方案2】:

    这是因为您要序列化的内容引用了MainViewModel。怎么样,我不知道。但我知道这不是魔法。

    如果您序列化 X 的实例,但由于类型 Y 不可序列化而失败,则 X 的实例持有对实例的引用Y 型。这是 100% 确定的。

    通常,您应该进行调试,并在序列化之前从上到下检查该对象图。对于二进制序列化,这包括事件,因为二进制序列化也会序列化事件侦听器。

    二进制序列化是如此 1.0.您应该研究序列化技术的最新发展。 NetDataContractSerializer 和 xaml 序列化非常适合您的大多数 .NET 需求。当您的类型不那么重要时,Json 很好。 这些都不会序列化事件侦听器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 2011-02-05
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      相关资源
      最近更新 更多