Serialising a label object with .Net Json

0

I am trying to serialise an object using json.Net but I am getting the following exception.

Newtonsoft.Json.JsonSerializationException: Error getting value from 'Parent' on 'System.Windows.Forms.Label+LabelAccessibleObject'. ---> System.Runtime.InteropServices.COMException: Interface not registered (Exception from HRESULT: 0x80040155)
   at Accessibility.IAccessible.get_accParent()
   at System.Windows.Forms.AccessibleObject.get_Parent()
   at System.Windows.Forms.Control.ControlAccessibleObject.get_Parent()
   at GetParent(Object )
   at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)

Here is the code I am using to serialise:

  var settings = new JsonSerializerSettings();
  settings.TypeNameHandling = TypeNameHandling.Objects;
  Console.WriteLine(JsonConvert.SerializeObject(y), Formatting.Indented, settings);

The strange thing is I thought the exception meant I needed to add an accessibility reference but adding it didn't fix anything.

Its also worth mentioning that y in this case is a Label object. Looks like the serialiser function is trying to read the accessibility property of y and failing.


EDIT: FYI I have installed it using the package manager as it recommends on the website so I doubt its running 32bit on 64 or something similar. Thanks.

c#
.net
winforms
serialization
json.net
asked on Stack Overflow Aug 10, 2015 by FaddishWorm • edited Aug 10, 2015 by Clemens

1 Answer

0

WinForms objects are quite complex, I wouldn't try to serialize everything. You can't re-create forms by doing that. One problem is the order that that controls are added to the form (which also controls how they are docked).

You need to create DTOs (simple objects with just the relevant properties) and serialize those instead.

public class LabelDTO
{
    public LabeLDTO(Label label)
    {
        Name = label.Name;
        Text = label.Text;
    }

    protected LabelDTO()
    {
    }

    public string Text { get; set; }
    public string Name { get; set; }
}

public class DtoFactory
{
    Dictionary<Type, Func<Control, object> _factories = new Dictionary<Type, Func<Control, object>();

    public DtoFactory()
    {
        _factories.Add(typeof(Label), ctrl => new LabelDTO(ctrl));
    }

    public object Create(Control control)
    {
        Func<Control, object> factoryMethod;
        return _factories.TryGetValue(control.GetType(), out factoryMethod)
            ? factoryMethod(control)
            : throw new NotSupportedException("Failed to find factory for " + control.GetType().FullName); 
    }
}


List<object> formData = new List<object>();
foreach (var control in Form.Controls) 
{
    var dto = DtoFactory.Create(control);
    formData.Add(dto);        
}

var json = JsonConvert.SerializeObject(formData);
answered on Stack Overflow Aug 10, 2015 by jgauffin

User contributions licensed under CC BY-SA 3.0