3

I have such BaseView

public abstract class BaseView 
{
    public enum ViewType
    {
        NOT_DEFINED,
        CHECK_BOX
    }

    virtual public string Title { get; } = string.Empty;
    virtual public string Name { get; } = string.Empty;
    virtual public string ConfigName { get; } = string.Empty;
    virtual public int DefaultValue { get; } = MCConstants.DEFAULT_VAL;
    virtual public ViewType Type { get; } = ViewType.NOT_DEFINED;

    public BaseView(string title, string configName, int defaultValue, ViewType viewType)
    {
        Title = title;
        Name =  title.Replace(' ', '_');
        ConfigName = configName;
        DefaultValue = defaultValue;
        Type = viewType;
    }
}

and his child

public class DynamicCheckBox : BaseView
{
    public bool IsChecked { get; set; }

    public DynamicCheckBox(string title, string configName, int defaultValue) : base(title, configName, defaultValue, ViewType.CHECK_BOX)
    {
        IsChecked = DefaultValue == MCConstants.TRUE ? true : false;
    }
}

Now I need to serialize List of DynamicCheckBox and then deserialize it. For this I wrote such methods

public static string ParseObjListToString<TYPE>(IList<TYPE> list)
{
    return JsonConvert.SerializeObject(new { list });         <--- This line
}

public static IList<TYPE> ParseStringToListOfObj<TYPE>(string value)
{
    return JsonConvert.DeserializeObject<IList<TYPE>>(value);
}

I get such error

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList`1[TV_MeshCreatorEngine.Base.BaseView]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'list', line 1, position 8.'

There is my test method

private void TestMethod()
{
    IList<BaseView> list = new List<BaseView>()
    {
        new DynamicCheckBox("titleOne", "configNameOne", 1)
    };

    var stringResult = JsonUtil.ParseObjListToString(list);
    IList<BaseView> listResult = JsonUtil.ParseStringToListOfObj<BaseView>(stringResult);
}

What am I doing wrong?

EDIT

If I change this method

public static string ParseObjListToString<TYPE>(IList<TYPE> list)
{
    return JsonConvert.SerializeObject(new { list });         <--- This line
}

to this

public static string ParseObjListToString<TYPE>(IList<TYPE> list)
{
    return JsonConvert.SerializeObject(list );         <--- This line
}

anyway I get error

Newtonsoft.Json.JsonSerializationException: 'Could not create an instance of type TV_MeshCreatorEngine.Base.BaseView. Type is an interface or abstract class and cannot be instantiated. Path '[0].IsChecked', line 1, position 14.'

haldo
  • 14,512
  • 5
  • 46
  • 52
Sirop4ik
  • 4,543
  • 2
  • 54
  • 121
  • I think you serialize a list of lists in your method. can you use this instead? return JsonConvert.SerializeObject(list); – Dmitri Tsoy Jan 20 '20 at 09:50
  • Does this answer your question? [Deserializing JSON to abstract class](https://stackoverflow.com/questions/20995865/deserializing-json-to-abstract-class) – Johnathan Barclay Jan 20 '20 at 09:59

1 Answers1

0

You are serializing object with field named list with type IEnumerable<> instead of serializing to array.

change

return JsonConvert.SerializeObject(new { list });

to

return JsonConvert.SerializeObject(list);

Edit: because your output JSON looks like: { list: [] }

Newtonsoft.Json cannot deserialize it to array []

You can also change deserialization to match your serialized object.

  • 1
    Then this should help: https://stackoverflow.com/questions/20995865/deserializing-json-to-abstract-class – Sławomir Pawluk Jan 20 '20 at 09:57
  • I did not understand exactly, did you mean that I need change `List` to array before serialization? – Sirop4ik Jan 20 '20 at 10:57
  • You cannot deserialize your array, because you are using abstract class. .NET is unable to instantiazie abstract class. So your options are: 1. Create converter from JSON to class derived from abstract class 2. Create POCO model, that is not based on abstract class, but has same Shape as your JSON – Sławomir Pawluk Jan 20 '20 at 11:06