SerializationException类型“未标记为可序列化” – 但它确实如此

在Windows窗体,.NET Framework 4.0中,我正在尝试序列化我编写的类的实例。

该类被标记为Serializable,但使用该类(显然)的forms不是。

我不想序列化表单的实例。 我想序列化我class上的数据。

我class上的所有东西都标记为Serializable,为什么我仍然得到SerializationException?

SerializationException.png

(点击>>这里<<在新窗口中打开图片全尺寸)

更新:

这是我的BrazierCuttoff课程及相关部分:

 [Serializable()] public class BrazierCuttoff : IEquatable { private int qty; private int[] joint, pass, shift; private float mult; private BrazierPay a, b, c, d, e; public event EventHandler BrazierCuttoffChanged; public const int MAXIMUMSMALLQUANTITY = 20; EnumeratedLevel[,] eLvArray; ///  /// Gets or Sets the Brazier Matrix values ///  /// 0=100%,1=95,2=90,3=85,4=80,5=75,6=70,7=65 /// 0=900,1=1200,2=1400,3=1600,4=1800,5=2000,6=2100,=2200 /// Brazier Matrix value public EnumeratedLevel this[int passRatioIndex, int minJointIndex] { get { return eLvArray[passRatioIndex, minJointIndex]; } set { eLvArray[passRatioIndex, minJointIndex] = value; } } ///  /// Initializes a new Form Values object using default values ///  public BrazierCuttoff() { A = new BrazierPay(5.0f); B = new BrazierPay(4.0f); C = new BrazierPay(3.0f); D = new BrazierPay(2.0f); E = new BrazierPay(1.0f); NA = new BrazierPay(0.0f); ShiftMinimum = new int[] { 12, 12, 12 }; PassRatio = new int[] { 100, 95, 90, 85, 80, 75, 70, 65 }; JointMinimum = new int[] { 900, 1200, 1400, 1600, 1800, 2000, 2100, 2200 }; eLvArray = new EnumeratedLevel[8, 8]; EnumeratedLevel level = EnumeratedLevel.NA_Silver; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { switch (y) { case 0: level = (x < 2) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break; case 1: level = (x == 0) ? EnumeratedLevel.C_Green : (x < 3) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break; case 2: level = (x < 2) ? EnumeratedLevel.C_Green : (x < 5) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break; case 3: level = (x == 0) ? EnumeratedLevel.D_Yellow : (x < 4) ? EnumeratedLevel.C_Green : (x < 6) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break; case 4: level = (x < 2) ? EnumeratedLevel.D_Yellow : (x < 5) ? EnumeratedLevel.C_Green : EnumeratedLevel.B_Blue; break; case 5: level = (x == 0) ? EnumeratedLevel.E_Orange : (x < 3) ? EnumeratedLevel.D_Yellow : (x < 6) ? EnumeratedLevel.C_Green : EnumeratedLevel.B_Blue; break; case 6: level = (x < 2) ? EnumeratedLevel.E_Orange : (x < 5) ? EnumeratedLevel.D_Yellow : EnumeratedLevel.C_Green; break; default: level = (x == 0) ? EnumeratedLevel.NA_Silver : (x < 5) ? EnumeratedLevel.E_Orange : EnumeratedLevel.D_Yellow; break; } eLvArray[x, y] = level; } } } private void broadcast() { if (BrazierCuttoffChanged != null) { BrazierCuttoffChanged(this, new EventArgs()); } } ///  /// Gets or Sets the A Pay Level data ///  public BrazierPay A { get { return a; } set { if (a != value) { a = value; broadcast(); } } } ///  /// Gets or Sets the B Pay Level data ///  public BrazierPay B { get { return b; } set { if (b != value) { b = value; broadcast(); } } } ///  /// Gets or Sets the C Pay Level data ///  public BrazierPay C { get { return c; } set { if (c != value) { c = value; broadcast(); } } } ///  /// Gets or Sets the D Pay Level data ///  public BrazierPay D { get { return d; } set { if (d != value) { d = value; broadcast(); } } } ///  /// Gets or Sets the E Pay Level data ///  public BrazierPay E { get { return e; } set { if (e != value) { e = value; broadcast(); } } } ///  /// Gets or Sets the N/A Pay Level data ///  public BrazierPay NA { get; private set; } public void Refresh() { const float delta = 0.01f; while (A.Dirty || B.Dirty || C.Dirty || D.Dirty || E.Dirty) { if (A.Dirty) { if (A.Value <= B.Value) B.Value = A.Value - delta; A.Dirty = false; } else if (B.Dirty) { if (B.Value <= C.Value) C.Value = B.Value - delta; if (A.Value <= B.Value) A.Value = B.Value + delta; B.Dirty = false; } else if (C.Dirty) { if (C.Value <= D.Value) D.Value = C.Value - delta; if (B.Value <= C.Value) B.Value = C.Value + delta; C.Dirty = false; } else if (D.Dirty) { if (D.Value <= E.Value) E.Value = D.Value - delta; if (C.Value <= D.Value) C.Value = D.Value + delta; D.Dirty = false; } else if (E.Dirty) { if (D.Value <= E.Value) D.Value = E.Value + delta; E.Dirty = false; } } } ///  /// Gets the minimum Average Joints requirement ///  public int AverageJoints { get { return JointMinimum[0]; } } ///  /// Gets the minimum Chamber Pass Ratio requirement ///  public int FirstTimePassRate { get { return PassRatio[PassRatio.Length - 1]; } } ///  /// Gets or sets the Minimum Average Joints requirements (Range: 0 @ 900 to 7 @ 2200) ///  public int[] JointMinimum { get { return joint; } set { if (joint != value) { joint = value; broadcast(); } } } ///  /// Gets or Sets the Chamber Pass Ratio levels (Range: 0 @ 100% to 7 @ 65%) ///  public int[] PassRatio { get { return pass; } set { if (pass != value) { pass = value; broadcast(); } } } ///  /// Gets or Sets the Integral Array of minimum shifts required to qualify for a bonus ///  public int[] ShiftMinimum { get { return shift; } set { if (shift != value) { shift = value; broadcast(); } } } ///  /// Gets or Sets the Small Workorder Multiplier (1 is default/disable) ///  public float SmallWoMulti { get { return mult; } set { if (mult != value) { mult = value; broadcast(); } } } ///  /// Gets or Sets the Small Workorder Quantity value (0 is disable) ///  public int SmallWoQty { get { return qty; } set { if (qty != value) { qty = value; broadcast(); } } } #region IEquatable Members public bool Equals(BrazierCuttoff other) { if (other != null) { if ((A == other.A) && (B == other.B) && (C == other.C) && (D == other.D) && (E == other.E) && (NA == other.NA)) { if ((ShiftMinimum == other.ShiftMinimum) && (PassRatio == other.PassRatio) && (JointMinimum == other.JointMinimum)) { return (eLvArray == other.eLvArray); } } } return false; } #endregion } 

这是上面类中使用的BrazierPay对象:

 [Serializable()] public class BrazierPay { float pay; public BrazierPay(float payLevel) { Dirty = false; pay = payLevel; } public float Value { get { return pay; } set { if (pay != value) { Dirty = true; pay = value; } } } public bool Dirty { get; set; } public string DollarValue { get { return string.Format("{0:C}", pay); } } public string Formatted { get { return string.Format("{0:F}", pay); } } public override string ToString() { return Formatted; } } 

我甚至将这个枚举类型标记为Serializable(但是,它不应该需要它):

 [Serializable()] public enum EnumeratedLevel { NA_Silver = Clicker.NA_Silver, // Color.Silver E_Orange = Clicker.E_Orange, // Color.Orange D_Yellow = Clicker.D_Yellow, // Color.Yellow C_Green = Clicker.C_Green, // Color.Lime B_Blue = Clicker.B_Blue, // Color.DodgerBlue A_Violet = Clicker.A_Violet, // Color.Violet } 

解决

我需要为EventHandler设置NonSerializedAttribute

无法在类中序列化事件委托(请参阅委托和序列化 )。

将字段标记为NonSerializedAttribute就像听起来一样简单。

从我的代码中,我只是添加了这一行:

 [field:NonSerializedAttribute()] public event EventHandler BrazierCuttoffChanged; 

这是您可以在任何JSON序列化中遇到的问题,包括MVC 4中的Web API。

我发现这篇文章在我获得序列化时非常有用,除了const int值。 任何const值都需要使用与Nick Freeman的答案相同的属性标记:

 [field: NonSerializedAttribute] const int iCantBeSerialized = 1; 
 [field:NonSerializedAttribute()] public event EventHandler BrazierCuttoffChanged; 

有同样的问题,我的可序列化NotifyObject基类的PropertyChanged EventHandler由一些进入序列化队列的viewmodels订阅。 将NonSerializedAddtribute添加到此EventHandler节省了我的一天。 🙂

BrazierMatrix2标记为[Serializable]