In Windows Forms, .NET Framework 4.0, I am trying to Serialize an instance of a class I wrote.
The class is marked as Serializable, but the form that uses the class (obviously) is not.
I do not want to Serialize an instance of the form. I want to Serialize the data I have in my class.
Everything in my class is marked as Serializable, so why am I still getting the SerializationException?
(Click >> HERE << to open image full-size in a new window)
Update:
Here is my BrazierCuttoff
class and related parts:
[Serializable()]
public class BrazierCuttoff : IEquatable<BrazierCuttoff> {
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;
/// <summary>
/// Gets or Sets the Brazier Matrix values
/// </summary>
/// <param name="passRatioIndex">0=100%,1=95,2=90,3=85,4=80,5=75,6=70,7=65</param>
/// <param name="minJointIndex">0=900,1=1200,2=1400,3=1600,4=1800,5=2000,6=2100,=2200</param>
/// <returns>Brazier Matrix value</returns>
public EnumeratedLevel this[int passRatioIndex, int minJointIndex] {
get { return eLvArray[passRatioIndex, minJointIndex]; }
set { eLvArray[passRatioIndex, minJointIndex] = value; }
}
/// <summary>
/// Initializes a new Form Values object using default values
/// </summary>
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());
}
}
/// <summary>
/// Gets or Sets the A Pay Level data
/// </summary>
public BrazierPay A { get { return a; } set { if (a != value) { a = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the B Pay Level data
/// </summary>
public BrazierPay B { get { return b; } set { if (b != value) { b = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the C Pay Level data
/// </summary>
public BrazierPay C { get { return c; } set { if (c != value) { c = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the D Pay Level data
/// </summary>
public BrazierPay D { get { return d; } set { if (d != value) { d = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the E Pay Level data
/// </summary>
public BrazierPay E { get { return e; } set { if (e != value) { e = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the N/A Pay Level data
/// </summary>
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;
}
}
}
/// <summary>
/// Gets the minimum Average Joints requirement
/// </summary>
public int AverageJoints { get { return JointMinimum[0]; } }
/// <summary>
/// Gets the minimum Chamber Pass Ratio requirement
/// </summary>
public int FirstTimePassRate { get { return PassRatio[PassRatio.Length - 1]; } }
/// <summary>
/// Gets or sets the Minimum Average Joints requirements (Range: 0 @ 900 to 7 @ 2200)
/// </summary>
public int[] JointMinimum { get { return joint; } set { if (joint != value) { joint = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the Chamber Pass Ratio levels (Range: 0 @ 100% to 7 @ 65%)
/// </summary>
public int[] PassRatio { get { return pass; } set { if (pass != value) { pass = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the Integral Array of minimum shifts required to qualify for a bonus
/// </summary>
public int[] ShiftMinimum { get { return shift; } set { if (shift != value) { shift = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the Small Workorder Multiplier (1 is default/disable)
/// </summary>
public float SmallWoMulti { get { return mult; } set { if (mult != value) { mult = value; broadcast(); } } }
/// <summary>
/// Gets or Sets the Small Workorder Quantity value (0 is disable)
/// </summary>
public int SmallWoQty { get { return qty; } set { if (qty != value) { qty = value; broadcast(); } } }
#region IEquatable<BrazierCuttoff> 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
}
This is the BrazierPay
object that is used in the class above:
[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; }
}
I even marked this enumerated type as Serializable (though, it should not need it):
[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
}
I needed to set a NonSerializedAttribute
for the EventHandler.
The event delegate could not be serialized in the class (see Delegates and Serialization).
Marking the field as NonSerializedAttribute
was as easy as it sounds.
From my code, I simply added this line:
[field:NonSerializedAttribute()]
public event EventHandler BrazierCuttoffChanged;
This is something you can run into with any JSON serialization, including Web API in MVC 4.
I found this post to be very helpful when I was getting a serialization except on a const int value. Any const value needs to be marked with the same attribute as in Nick Freeman's answer:
[field: NonSerializedAttribute]
const int iCantBeSerialized = 1;
[field:NonSerializedAttribute()]
public event EventHandler BrazierCuttoffChanged;
Had the same problem, the PropertyChanged EventHandler of my serializable NotifyObject base class was subscribed by some viewmodels which went into the serialization queue therefore. Adding the NonSerializedAddtribute to this EventHandler saved my day. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With