0

I'm having some trouble with serializing a ObservableCollection of Lines (Shape). I'm developing for Windows RT and I'm using JSON.NET v5.02. I'm getting the following exception for the code below:

ObservableCollection<Line> lines;
//some code
string linesString = JsonConvert.SerializeObjectAsync(lines); // problem

An exception of type Newtonsoft.Json.JsonSerializationException occurred in mscorlib.dll but was not handled in user code

Additional information: Error getting value from 'X1' on 'Windows.UI.Xaml.Shapes.Line'.

If there is a handler for this exception, the program may be safely continued.

Is this a bug and is there a possible workaround?

Leon Cullens
  • 12,276
  • 10
  • 51
  • 85
w.donk
  • 3,252
  • 1
  • 18
  • 15

2 Answers2

2

Your problem is a cross thread problem. When using await JsonConvert.SerializeObjectAsync(lines); that function will be executed in another thread (not the UI thread). Since a Windows.UI.Xaml.Shapes.Line is a UIElement and was created in the UI (main) thread you can't access the properties of the object in another thread. The solution would be to convert it to a simpler object that doesn't have this restrictions.

Besides, a Windows.UI.Xaml.Shapes.Line contains a lot of information, Visibility, IsEnabled etc, I think you would only need the X1, X2, Y1 and Y2. So you could just use this:

string s = await JsonConvert.SerializeObjectAsync(lines
             .Select(l => new 
                     {
                         l.X1,
                         l.X2,
                         l.Y1,
                         l.Y2
                     }).ToArray()); 

In this way, you get the properties you need in your UI (main) thread. Then pass that array to the serialize function. This way it works.

string s would now contain:

[{"X1":20.0,"X2":20.0,"Y1":40.0,"Y2":40.0},{"X1":20.0,"X2":20.0,"Y1":40.0,"Y2":40.0},{"X1":20.0,"X2":20.0,"Y1":40.0,"Y2":40.0},{"X1":20.0,"X2":20.0,"Y1":40.0,"Y2":40.0}]

SynerCoder
  • 12,493
  • 4
  • 47
  • 78
  • Don't forget to use the `.ToArray()` if you don't you create a statemachine with the `.Select` A statemachine will be executed when it is needed, that is in the `SerializeObjectAsync` which is in another thread. By calling `.ToArray()` you force the statemachine to run and create an array in the UI thread. – SynerCoder Apr 11 '13 at 09:41
  • Hi@SynerCoder Can I use your solution for my problem please let me know thanks in advance...http://stackoverflow.com/questions/17105051/save-information-of-line-and-images – Mohit Jun 14 '13 at 10:05
0

I am not sure whether Json.Net allow serializing framework class object. I tried with this.

public class CustomLine
{
    public double X1 { get; set; }
    public double X2 { get; set; }
    public double Y1 { get; set; }
    public double Y2 { get; set; }
}

I Changed the Line to CustomLine line. If you want to use Line class then retrieve properties X1, X2, Y1, Y2 and then assign it to CustomLine class properties.

Farhan Ghumra
  • 15,180
  • 6
  • 50
  • 115