views:

19

answers:

2

Alright I'm a bit baffled by this one. Changing an unrelated int property on my ViewModel seems to be making my Model unserializable.

I have an object which tracks the best time to contact someone. It can be set to Anyday, Weekdays, Evenings, SpecificDays and to Anytime, Mornings, Afternoons, Evenings, and SpecificTimes. When the object is saved, it gets serialized and sent to a WCF server.

In essence, the object is a collection of 7 Days. Each Day contains an int for the day of week, a collection of TimeSpans which define good calling hours for that day, an a collection of boolean flags which define which "shortcut" groups of times were selected (Morning, Afternoon, Evening, etc).

I am using MVVM and have a VM to handle this class. The only property the VM contains other then the collection of days is an int value of which "shortcut" group for the weekdays are defined (Weekdays, Weekends etc).

Everything works absolutely fine until I set the "shortcut" group for Weekdays to "SpecificDays". Upon saving, I get an error trying to pass the object to the WCF server. The error says it cannot serialize a parameter with the inner exception shown below (keep in mind that WCF errors are very generic and often do not point to the problem at all). Here's a screenshot of what I'm trying to do:

Sample Image

This doesn't make sense to me, because the ShortcutWeekday is not sent to the WCF server at all. The only thing that goes is the collection of Days. And another puzzling thing, clicking on the "Specific Days" radio button, then clicking back to another selection will make the WCF call fail as well. Also, if the problem was with my class itself, wouldn't it have failed saving anytime, not just for the Specific Days?? I double-checked the property values of the collection of Days using the example above, and the object properties are set exactly the same.

Inner Exception:

"Type 'System.DelegateSerializationHolder+DelegateEntry' with data contract name 
'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System' 
is not expected. Consider using a DataContractResolver or add any types not known 
statically to the list of known types - for example, by using the KnownTypeAttribute 
attribute or by adding them to the list of known types passed to DataContractSerializer."

ViewModel properties:

// Used to track which Radio Button is selected
private int _selectedWeekdayGroup = 0;

// Object holding the current BestContactTime
private BestContactTime _bestContactTime;

// Shortcut to multiple Days in BestContactTime
public int SelectedWeekdayGroup
{
    get { return _selectedWeekdayGroup; }
    set
    {
        //UpdateCallableDays(value); // This updates the BestContactTime.Days collection
        _selectedWeekdayGroup = value;
        //OnPropertyChanged("SelectedTimesGroups"); // This property is just which set of ShortcutTimes are displayed in checkboxes 
    }
}

BestContactTime:

// Should always have only 7 objects, one per day of week
public ObservableCollection<ContactDay> Days;

Contact Day:

public int WeekDay;
public SortableObservableCollection<TimeSpan> CallableTimes;
public SortableObservableCollection<bool> CallableTimeGroups;

SortableObservableCollection is just a class which inherits from ObservableCollection with some additional methods such as Sorting and AddRange.

+1  A: 

It looks like setting the property causes an event handler to be added.
Try adding [field: NonSerialized] to the event.

SLaks
The only event handler is the PropertyChanged event and it already has that attribute
Rachel
@Rachel: What about `SortableObservableCollection`?
SLaks
I apologize, apparently I am mistaken. I thought all my Models inherited from a base model class which does have that attribute, but apparently this one doesn't. Thank you so much! I've wasted so much time today trying to figure this one out....
Rachel
+2  A: 

You can use my sertool to verify this for sure, but I suspect this is just a case of something non-serializable attaching to an event in your model, and therefore the serialization fails.

You can fix with:

[field:NonSerialized]

to the offending event(s).

HTH,
Kent

Kent Boogaart
Thanks Kent, this was correct. I am marking SLaks response as the answer because he posted it first, however I'll still upvote yours .
Rachel