Daniel Perez
Daniel Perez

Reputation: 4332

InvalidDataContractException on WP7 application on class that is serializable

I'm having an strange error when trying to save an object into isolated storage. I have a class that has some properties, here's the code :

[DataContract]
    public class ExerciseStatistic
    {
        [XmlIgnore]
        public int CorrectAnswers
        {
            get
            {
                return Attempts.Where(a => a.AttemptAnswerIsCorrect).Count();
            }
        }

        [XmlIgnore]
        public int IncorrectAnswers
        {
            get
            {
                return Attempts.Where(a => !a.AttemptAnswerIsCorrect).Count();
            }
        }

        [XmlIgnore]
        public int AnswerAttempts
        {
            get { return Attempts.Count; }
        }

        public List<AnswerAttempt> Attempts { get; set; }

        public ExerciseStatistic()
        {
            Attempts = new List<AnswerAttempt>();
        }
    }

    public class AnswerAttempt
    {
        public DateTime AttemptDate { get; set; }
        public string AttemptTargetName { get; set; }
        public string AttemptName { get; set; }
        public bool AttemptAnswerIsCorrect { get; set; }
    }

However, when trying to save it with this sentence :

IsolatedStorageSettings.ApplicationSettings["a"] = new ExerciseStatistic()
                                                {
                                                    Attempts = new List<AnswerAttempt>()
                                                                                {
                                                                                    new AnswerAttempt()
                                                                                        {
                                                                                            AttemptAnswerIsCorrect = true,
                                                                                            AttemptDate = DateTime.Now,
                                                                                            AttemptName = "lala",
                                                                                            AttemptTargetName = "lala2"
                                                                                        },
                                                                                    new AnswerAttempt()
                                                                                        {
                                                                                            AttemptAnswerIsCorrect = false,
                                                                                            AttemptDate = DateTime.Now,
                                                                                            AttemptName = "lalab",
                                                                                            AttemptTargetName = "lalab2"
                                                                                        }
                                                                                }
                                                };

I'm getting an exception like this one (i changed a bit the signature of the code with fake names, but for the example it serves its purpose) :

Type 'XX.Model.FirstClass.SecondClass' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.

I don't understand why the serializer is trying to serialize an object of my model (which is not serializable) when the class that I'm giving it doesn't have any references to that kind of type... what am i missing? -> nope, i don't want to add datacontract attributes to classes that i don't need and am not planning to serialize, so please don't answer with this :)

Upvotes: 1

Views: 747

Answers (3)

Brian M
Brian M

Reputation: 11

You might experience this problem if you work through the reference procedure in "Walkthrough: Consuming OData with MVVM for Windows Phone" at http://msdn.microsoft.com/en-us/library/hh394007(v=VS.92).aspx

When you get to the point where you call :

  Return DataServiceState.Serialize(_context, collections);

You might get an InvalidDataContractException with the message:

Type 'DataBoundApp1.Northwind.NorthwindEntities' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.

Thanks to the answer by Daniel Perez, I was able to resolve this problem and I am documenting my steps to clarify the solution for others:

  1. Show hidden files in Solution Explorer
  2. Open the file "Reference.cs" (under your Service Reference, expand Reference.datasvcmap)
  3. If your Data Service Context class is missing the [DataContract] attribute, add it as shown here:

.

namespace OCC.WindowsPhone.OrlandoCodeCampService
{    
    [DataContract]  <--- I ADDED THIS
    public partial class OrlandoCodeCampEntities : global::System.Data.Services.Client.DataServiceContext
    {..}

Once I added the DataContract attribute, the problem went away!

Upvotes: 1

Daniel Perez
Daniel Perez

Reputation: 4332

I don't think that this is a proper answer, but it's what i had to do in order to fix it. After changing some more the code, i realised that this was failing EVEN if I wasn't saving anything to the isolated storage. Just declaring a DataContract attribute on the type made the error arise. I must think that WP7's framework at some point is parsing all classes that have this attribute, and for some strange and obscure reason (which i can't find) it's looking for them in other classes as well. I added the DataContract attributes in the classes that the framework is complaning about, and also some KnownType attributes as well, and everything started to run smoothly... weird weird... if someone can shed some light into this, i'd be happy (i hate it when i solve a problem but without knowing the exact cause)

Upvotes: 0

thumbmunkeys
thumbmunkeys

Reputation: 20764

It seems to me you try to exclude properties from serialization by using XmlIgnore.

From the documentation:

You can opt out members from serialization by using the IgnoreDataMemberAttribute.

so try using IgnoreDataMemberAttribute instead of XmlIgnore to opt out members from serialization.

I also had some troubles with DataContract in the very same situation as you, therefore I reverted to plain old XML serialization to strings, which i then stored in isolated storage. This also eases debugging.

Upvotes: 0

Related Questions