Public IDictionary member of ViewModel class will not serialize via DataContractSerializer

125 views Asked by At

I have a class that's my view model for a windows 8.1 universal application. I want to be able to serialize / deserialize this class as necessary. I have this working with the exception of the IDictionary public property. This property is being skipped. When I explicitly tell the DataContractSerializer to serialized by itself, it works as expected.

Why is it not being picked up by the DataContractSerializer when serializing the view model class? I have all the KnowType issues worked out as you'll see when I serialize the DataDictionary directly.

Here is the class in question

[KnownType( typeof( ViewModel ) )]
public class AViewModel : ViewModelBase
{
      public ViewModel()
      {
         DataDictionary = new Dictionary<double, IData>();
         SaveCommand = new RelayCommand( () => Save() );
         LoadCommand = new RelayCommand( () => Load() );
      }

      private string _firstName;
      public string FirstName { get { return _firstName; } set { Set( () => FirstName, ref _firstName, value ); } }

      private string _lastName;
      public string LastName { get { return _lastName; } set { Set( () => LastName, ref _lastName, value ); } }

      private IDictionary<double, IData> _dataDictionary;
      public IDictionary<double, IData> DataDictionary { get { return _dataDictionary; } private set { _dataDictionary = value; } }

      public ICommand SaveCommand { get; private set; }
      public ICommand LoadCommand { get; private set; }

      private async void Save()
      {
        //logic will go here, example in unit test below
      }
}

Here are the sub classes related to the IData

public interface IData
{
   string Type { get; set; }
}

[KnownType( typeof( BlueData ) )]
public class BlueData : IData
{
   public string String1 { get; set; }
   public string Type { get; set; }
}

[KnownType( typeof( GreenData ) )]
public class GreenData : IData
{
   public string Type { get; set; }
   public string String1 { get; set; }
}

Here is the code that I'm using to build the serialization

ViewModel model = new ViewModel();
model.FirstName = "First";
model.LastName = "Last";
model.DataDictionary.Add( 1.2, new BlueData { String1 = "TestBlueData", Type = "BlueData" } );

MemoryStream memoryStream = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer( typeof( ViewModel ) );
serializer.WriteObject( memoryStream, model );

memoryStream.Seek( 0, SeekOrigin.Begin );

string xml;
using ( StreamReader reader = new StreamReader( memoryStream ) )
{
    xml = reader.ReadToEnd();
}

Here is the xml output I'm getting from the above code

<ViewModel xmlns="http://schemas.datacontract.org/2004/07/ApplicationNamespace.ViewModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><FirstName>First</FirstName><LastName>Last</LastName></ViewModel>

When I call DataContractSerializer on model.DataDictionary directly, I get the following

<ArrayOfKeyValueOfdoubleanyType xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><KeyValueOfdoubleanyType><Key>1.2</Key><Value i:type="a:BlueData" xmlns:a="http://schemas.datacontract.org/2004/07/ApplicationNamespace"><a:String1>TestBlueData</a:String1><a:Type>BlueData</a:Type></Value></KeyValueOfdoubleanyType></ArrayOfKeyValueOfdoubleanyType>
1

There are 1 answers

6
Jon On BEST ANSWER

If you change the setter of your DataDictionary property from 'private' to 'public', then it should work as expected