cannot be deserialized because the member * is not public -- no member of that name!

Mar 5, 2011 at 7:48 PM
Edited Mar 5, 2011 at 7:54 PM

Hi, I recieved this stack trace from a user:

 

 

System.Security.SecurityException: The data contract type 'System.Runtime.Serialization.KeyValue`2[[System.String, mscorlib, Version=3.7.0.0, Culture=neutral, PublicKeyToken=969DB8053D3322AC],[DropNet.Models.MetaData, DropNet.WindowsPhone, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' cannot be deserialized because the member 'Key' is not public. Making the member public will fix this error. Alternatively, you can make it internal, and use the InternalsVisibleToAttribute attribute on your assembly in order to enable serialization of internal members - see documentation for more details. Be aware that doing so has certain security implications. ---> System.MethodAccessException: Attempt to access the method failed: System.Runtime.Serialization.KeyValue`2.set_Key(System.String)
� System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
� System.RuntimeType.InternalInvokeMember(Type thisType, String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters, StackCrawlMark& stackMark)
� System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.SetMemberValue(Object newInstance, Object value, String memberName, Type typeToInvokeOn)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, Object newInstance, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertDictionaryToClassDataContract(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, Object deserializedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, Object newInstance, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertDictionaryToClassDataContract(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream)
� RapidRepository.Serialiser.Deserialise(Type viewType, String stringToDeserialise)
� RapidRepository.Serialiser.Deserialise[T](String stringToDeserialise)
� RapidRepository.RapidContext.GetAll[TEntity]()
� RapidRepository.RapidRepository`1.GetAll()
� MyApp.MainViewModel.LoadData()
� MyApp.MainPage.MainPage_Loaded(Object sender, RoutedEventArgs e)
� System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
� MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

� System.Runtime.Serialization.Json.ObjectToDataContractConverter.SetMemberValue(Object newInstance, Object value, String memberName, Type typeToInvokeOn)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, Object newInstance, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertDictionaryToClassDataContract(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, Object deserializedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ReadClassDataContractMembers(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, Object newInstance, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.ObjectToDataContractConverter.ConvertDictionaryToClassDataContract(DataContractJsonSerializer serializer, ClassDataContract dataContract, Dictionary`2 deserialzedValue, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ConvertObjectToDataContract(DataContract contract, Object value, XmlObjectSerializerReadContextComplexJson context)
� System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream)
� RapidRepository.Serialiser.Deserialise(Type viewType, String stringToDeserialise)
� RapidRepository.Serialiser.Deserialise[T](String stringToDeserialise)
� RapidRepository.RapidContext.GetAll[TEntity]()
� RapidRepository.RapidRepository`1.GetAll()
� MyApp.MainViewModel.LoadData()
� MyApp.MainPage.MainPage_Loaded(Object sender, RoutedEventArgs e)
� System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
� MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)


The problem is, the object referenced:  DropNet.Models.MetaData HAS no property named "Key".

 

 [DataContract]
    public class MetaData
    {
        [DataMember]
        public string Hash { get; set; }
        public bool Thumb_Exists { get; set; }
        [DataMember]
        public long Bytes { get; set; }
        [DataMember]
        public string Modified { get; set; }
        [DataMember]
        public string Path { get; set; }
        public bool Is_Dir { get; set; }
        public bool Is_Deleted { get; set; }
        [DataMember]
        public string Size { get; set; }
        public string Root { get; set; }
        public string Icon { get; set; }
        [DataMember]
        public List<MetaData> Contents { get; set; }
}

Any ideas?  I am using that object in a dictionary:

 

[DataMember]
        public Dictionary<string, MetaData> DropBoxDirectoryListing{get;set;}

But I would think if this was a problem for ONE user, it would be a problem all the time.

Thanks in advance for any ideas you might have.
--Jason

 

 

 


Coordinator
Mar 5, 2011 at 9:36 PM

Hi Jason,

I'll try and reproduce and get back to you but I agree that it is strange that it is only affecting one user.

Sean.

Mar 5, 2011 at 9:46 PM
Edited Mar 6, 2011 at 2:17 AM
That would be great of you! Good luck reproducing, I couldn't!

--Jason
from my Focus (windows phone 7)

 

Coordinator
Mar 5, 2011 at 9:56 PM

Hi Jason,

I've just done the following test and it seems to be fine (assuming the test is similar to what you are doing), could you give me any more information around the specific code that was trying to access the dictionary key?

Cheers,

Sean.

 // Constructor
        public MainPage()
        {
            InitializeComponent();

            RapidRepository<MyEntity> repository = new RapidRepository<MyEntity>();

            MyEntity entity = new MyEntity
            {
                DropBoxDirectoryListing = new Dictionary<string,MetaData>()
            };
            entity.DropBoxDirectoryListing.Add("myTestItem", new MetaData { Path = "test" });

            repository.Add(entity);

            RapidContext.CurrentContext.SaveChanges();

            var entityFromDB = repository.GetAll()[0].DropBoxDirectoryListing["myTestItem"];

        }
using System.Collections.Generic;
using System.Runtime.Serialization;
using RapidRepository;

namespace DictionarySerialisationError
{
    [DataContract]
    public class MyEntity : IRapidEntity
    {
        [DataMember]
        public System.Guid Id { get; set; }

        [DataMember]
        public Dictionary<string, MetaData> DropBoxDirectoryListing { get; set; }
    }

    [DataContract]
    public class MetaData
    {
        [DataMember]
        public string Hash { get; set; }
        public bool Thumb_Exists { get; set; }
        [DataMember]
        public long Bytes { get; set; }
        [DataMember]
        public string Modified { get; set; }
        [DataMember]
        public string Path { get; set; }
        public bool Is_Dir { get; set; }
        public bool Is_Deleted { get; set; }
        [DataMember]
        public string Size { get; set; }
        public string Root { get; set; }
        public string Icon { get; set; }
        [DataMember]
        public List<MetaData> Contents { get; set; }
    }

}

 
Coordinator
Mar 5, 2011 at 10:22 PM

Hi Jason,

Just did a quick google and found that other people have had similar issues using dictionaries with the DataContractJsonSerializer: eg. http://stackoverflow.com/questions/4199321/how-to-deserialize-a-dictionary-using-datacontractjsonserializer

Although in your case it's strange as it has only failed for one user (or is there a chance it it is failing for more but you have only had 1 report?).

However, it's also strange that it seems to work fine in test.

This is definitely a tricky one, I would try and get as much info as possible

Sorry I couldn't be much more help, let me know if you get more info and need to me to help take a look.

Have a great weekend.

Sean.

Mar 6, 2011 at 2:36 AM

Thanks for looking into it, Sean!  Your test basically hit it on the head exactly.  

The user shared with me a backup of his data which unfortunately doesn't include his whole RapidRepository, just the data fields loaded into my Model.  

I loaded those up on my device with a problem. That is probably all of the information I am going to get.  Seems to me like some corruption in his Isolated Storage, so I advised him to uninstall and reinstall the app.

There is a chance that it is failing for more but only reported by 1, but it is also known that more than 500 users have loaded the app and all have passed through this block of code.  Many have discussed OTHER aspects of the app, so at least SOME (many)
other users do not have the issue.

The structure of the code is basically identical to the default Visual Studio template for a Windows Phone 7 Silverlight app.  If you place this into the MainViewModel.LoadData, you'll be identical to my setup:

 DataSetRepository repo = new DataSetRepository();
                List<DataSetViewModel> repoDataSets = (List<DataSetViewModel>)repo.GetAll();

DataSetRepository matches your example of a specialized RapidRepository exactly. 

public class DataSetRepository : RapidRepository<DataSetViewModel>
    {

DataSetViewModel has a boatload of [DataMember] properties, but only one which uses the model referenced in the error.

I guess it's case closed unless some other information comes to light.

Thank you again, you are a great and very helpful developer.  Rapid Repository is terrific, thank you so much for developing & sharing it.

--Jason

Coordinator
Mar 6, 2011 at 8:38 PM

Thanks Jason, glad you're finding it useful.

Hopefully this is just a one off as you say, it sounds like it possibly is as you have such a large number of users not experiencing it.

Here to help if it crops up again.

Cheers,

Sean.