I'm receiving varying JSONs with nested json objects and json arrays to C# app, and parsing them using Newtonsoft.JSON . I'm sending this data to MATLAB app, and want to send it as plain as I can for the MATLAB to parse the .NET types to MATLAB correctly.
For that, I convert the JObject 's to Dictionary<string, dynamic> . I use dynamic so that the MATLAB will get int , double , String instead of object always.
I also convert the JArray 's to object[] (using similar ToObject() function as in that thread).
What I'm missing is a way to fully convert JArray 's to double[] , int[,] . etc, if they are actually of that type. This will enable the MATLAB to parse them to MATLAB's double , int32 , etc correctly.
Is there a way of achieving this? Can it also be applied to multidimensional arrays?
Clarification: If I'm getting arrays of strings, I don't mind leaving it object[] . I mostly care for numeric multidimensional arrays.
EDIT:
As MATLAB prefer jagged arrays over multidimensional, so do I :)
Existing Code:
I currently expose the following Struct -like type to MATLAB, as it's not possible to marshal MATLAB structs to C#:
[JsonConverter(typeof(StructConverter))]
public class Struct
{
[JsonExtensionData]
Dictionary<string, dynamic> dict;
public Struct() => dict = new Dictionary<string, dynamic>();
public Struct(Dictionary<string, dynamic> d) => dict = d;
public string[] GetKeys() => dict.Keys.ToArray();
public void Set(string key, dynamic value) => dict[key] = value;
public void SetVector(string key, int[] value) => dict[key] = value;
public void SetVector(string key, double[] value) => dict[key] = value;
public dynamic Get(string key) => dict[key];
}
Where StructConverter is my current converter:
public class StructConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return ReadValue(reader);
}
private dynamic ReadValue(JsonReader reader)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
return ReadObject(reader);
case JsonToken.StartArray:
return ReadArray(reader);
default:
return reader.Value;
}
}
private dynamic ReadObject(JsonReader reader)
{
MatNet.Struct s = new MatNet.Struct();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string propName = reader.Value.ToString();
if (!reader.Read()) throw new Exception("Unexpected end when reading ExpandoObject.");
s.Set(propName, ReadValue(reader));
break;
case JsonToken.Comment:
break;
case JsonToken.EndObject:
return s;
}
}
throw new Exception("Unexpected end when reading ExpandoObject.");
}
private dynamic ReadArray(JsonReader reader)
{
List<dynamic> list = new List<dynamic>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Comment:
break;
default:
list.Add(ReadValue(reader));
break;
case JsonToken.EndArray:
return list.ToArray();
}
}
throw new Exception("Unexpected end when reading ExpandoObject.");
}
}
I'm able to serialize and deserialize the following, but the arrays are of object[] instead of int[] , string[] and double[] :
var d = new MatNet.Struct();
d.Set("a", new int[] { 1, 2, 4, 8, 16 });
d.Set("b", new string[] { "qwer", "tyui", "asdf", "ghjk" });
d.Set("c", new double[,] { {1, 3}, {2, 4}, {5, 7}, {6, 8} });
d.Set("d", new MatNet.Struct());
var json = JsonConvert.SerializeObject(d);
dynamic x = JsonConvert.DeserializeObject<MatNet.Struct>(json);
|