Jonghwan Hyeon
Jonghwan Hyeon

Reputation: 77

I don't know why my class cannot be serialized

I completed coding my application. But when I click start button, my app raised a exceptions.. :'(

A first chance exception of type 'System.Runtime.Serialization.InvalidDataContractException' occurred in System.Runtime.Serialization.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
A first chance exception of type 'System.Runtime.Serialization.InvalidDataContractException' occurred in System.Runtime.Serialization.dll

So I saw argument e of 'Application_UnhandledException', and I could know the reason. "'Type 'GPACalculator.Subject' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute."

I just make my class using default data types..

public class Subject : INotifyPropertyChanged
{
    private string name;
    private GradePoint gradePoint;
    private int credit;

    public Subject(string name)
    {
        Name = name;
        GradePoint = new GradePoint();
    }

    public string Name
    {
        get { return name; }
        set
        {
            Debug.WriteLine("Name: " + value);
            if (name != value)
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }

    }

    public GradePoint GradePoint
    {
        get { return gradePoint; }
        set
        {
            if (gradePoint != value)
            {
                gradePoint = value;
                OnPropertyChanged("GradePoint");
            }
        }
    }

    public int Credit
    {
        get { return credit; }
        set
        {
            if (credit != value)
            {
                credit = value;
                OnPropertyChanged("Credit");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}


public class GradePoint : INotifyPropertyChanged
{
    private string mainGradePoint;
    private string subGradePoint;
    private int credit;

    public int Credit
    {
        get { return credit; }
        set
        {
            if (credit != value)
            {
                credit = value;
                OnPropertyChanged("Credit");
            }
        }
    }

    public string MainGradePoint
    {
        get { return mainGradePoint; }
        set
        {
            value = value.ToUpper();
            if (mainGradePoint != value)
            {
                mainGradePoint = value;
                OnPropertyChanged("MainGradePoint");
            }
        }
    }

    public string SubGradePoint
    {
        get { return subGradePoint; }
        set
        {
            if (subGradePoint != value)
            {
                subGradePoint = value;
                OnPropertyChanged("SubGradePoint");
            }
        }
    }

    public override string ToString()
    {
        return string.Format("{0}{1}", mainGradePoint, subGradePoint);
    }

    public double ToDouble(double perfectScore = 4.5F)
    {
        double gap = perfectScore - Math.Floor(perfectScore);
        double value;


        switch (mainGradePoint)
        {
            case "A":
                value = 4.0;
                break;
            case "B":
                value = 3.0;
                break;
            case "C":
                value = 2.0;
                break;
            case "D":
                value = 1.0;
                break;
            default:
                value = 0.0;
                return value;
        }

        switch (subGradePoint)
        {
            case "+":
                value += gap;
                break;
            case "-":
                value -= gap;
                break;
        }

        return value;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

The above is my class..

please help me

Upvotes: 6

Views: 20636

Answers (5)

Anders Forsgren
Anders Forsgren

Reputation: 11111

Start by decorating your classes with the appropriate attributes for the serializer you want to use, e.g. [Serializable] for BinaryFormatter, or [DataContract] for contract based formatters.

Note: If you use the [Serializable] attribute, remember to mark the event fields with [field:NonSerialized] otherwise all the listeners of those events will be serialized as well.

Upvotes: 13

OKEEngine
OKEEngine

Reputation: 908

This question is redundant.

How to ignore Event class member for binary serialization?

You missed [Serializable] attribute in your class and also because event is not serialable you need to mark it as [field: NonSerialized] to your delegate event.

Upvotes: 0

Rohith
Rohith

Reputation: 2091

You could try marking the class with the attribute

[DataContract]
public class Subject : ...

or mark it serializable like so:

[Serializable]
public class Subject : ...

Upvotes: 2

Ankit
Ankit

Reputation: 6664

Both class should be serializable in this case. Add [Serializable] to the class

Upvotes: 0

Darren Lewis
Darren Lewis

Reputation: 8488

As the error states you need to define your class as serializable by decorating it with the DataContract attribute on the class and DataMember attribute to it's properties. Only public properties decorated with DataMember can be serialized. Your methods and events cannot.

[DataContract]
public class Subject
{
    [DataMember]
    public string Name{get;set;}
}

More info here

Upvotes: 6

Related Questions