A solution to an 'Unspecified error' when calling GetNavigationState via the SuspensionManager on Windows Phone 8.1

A common approach to communicate between page-navigations is to send data as a parameter when navigating. This parameter can all an object of all kinds - both value and reference types. However there's one gotcha: If you call Frame.GetNavigationState() and you've passed anything other than a simple type like guid, string or numerics you'll get an unspecified error and a COM exception like this:

{System.Runtime.InteropServices.COMException (0x80004005): Unspecified error

GetNavigationState doesn't support serialization of a parameter type which was passed to Frame.Navigate.
   at Windows.UI.Xaml.Controls.Frame.GetNavigationState()
   at xx.Common.SuspensionManager.SaveFrameNavigationState(Frame frame)
   at xx.Common.SuspensionManager.<SaveAsync>d__11.MoveNext()}

I passed the SelectedItem from a List as a parameter to a details page and that caused the exception when I tried to tombstone and save the page state using the SuspensionManager.

I looked up the documentation from MSDN and it's all there in black and white:

Note: The serialization format used by these methods is for internal use only. Your app should not form any dependencies on it. Additionally, this format supports serialization only for basic types like string, char, numeric and GUID types.
— https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.frame.getnavigationstate

My solution to this was to serialize my object as json using the Json.NET nuget package and sending the object as a string and deserializing it on the details page.

public void NavigateToDetails(Author author)
{
    string json = JsonConvert.SerializeObject(author, Formatting.Indented);
    NavigationHelper.NavigateTo<AuthorPage>(false, json);
}

And on the details page I simply deserialize it: 

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
     base.OnNavigatedTo(e);
     Author author = JsonConvert.DeserializeObject<Author>(e.Parameter.ToString());
     //// Do something with author
}

This is a simple work around that will work out of the box with the SuspensionManager shipped with Windows Phone 8.1. You might still run into trouble if you serialize huge lists as json and pass that as a parameter, but in those cases I'd say you're most likely doing something wrong. 

Feel free to comment and reach out if you have any comments or additions.

P.S Make sure you follow me on twitter @deanihansen for more news, design tips, articles and how-to's.