Browse Source

Fixed CoreTableJsonConverter

Kenric Nugteren 1 month ago
parent
commit
1b3d6e1fbd
2 changed files with 66 additions and 34 deletions
  1. 55 33
      InABox.Core/CoreTable/CoreTableJsonConverter.cs
  2. 11 1
      InABox.Core/Serialization.cs

+ 55 - 33
InABox.Core/CoreTable/CoreTableJsonConverter.cs

@@ -7,7 +7,6 @@ namespace InABox.Core
 
     public class CoreTableJsonConverter : CustomJsonConverter<CoreTable>
     {
-
         public override void Write(Utf8JsonWriter writer, CoreTable value, JsonSerializerOptions options)
         {
             if (value == null)
@@ -17,29 +16,29 @@ namespace InABox.Core
             }
             
             writer.WriteStartObject();
+
+            // Columns
             writer.WritePropertyName("Columns");
             writer.WriteStartObject();
             foreach (var column in value.Columns)
-                writer.WriteString(column.ColumnName, column.DataType.ToString());
+                writer.WriteString(column.ColumnName, column.DataType.EntityName());
             writer.WriteEndObject();
             
-            writer.WriteStartObject();
-            writer.WritePropertyName("Columns");
+            // Rows
+            writer.WritePropertyName("Rows");
             writer.WriteStartArray();
             foreach (var row in value.Rows)
             {
                 writer.WriteStartArray();
                 foreach (var column in value.Columns)
                 {
-                    var val = row[column.ColumnName];
                     WriteJson(writer, row[column.ColumnName]);
                 }
                 writer.WriteEndArray();
             }
-            writer.WriteEndObject();
-            writer.WriteEndObject();
-
+            writer.WriteEndArray();
 
+            writer.WriteEndObject();
         }
         
         public override CoreTable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
@@ -51,40 +50,65 @@ namespace InABox.Core
             try
             {
                 reader.Read();
-                if (reader.TokenType == JsonTokenType.PropertyName)
+                while(reader.TokenType != JsonTokenType.EndObject)
                 {
-                    var propertyName = reader.GetString();
-                    reader.Read();
-                    if (propertyName == "Columns")
+                    if (reader.TokenType == JsonTokenType.PropertyName)
                     {
-                        while (reader.TokenType != JsonTokenType.EndObject)
+                        var propertyName = reader.GetString();
+                        reader.Read(); // Move to property value
+                        if (propertyName == "Columns")
                         {
-                            string name = reader.GetString()!;
-                            reader.Read(); // Advance to the property value
-                            var type = reader.GetString();
-                            result.Columns.Add(new CoreColumn { ColumnName = name, DataType = CoreUtils.GetEntity(type ?? string.Empty) });
-                            reader.Read();
+                            if(reader.TokenType != JsonTokenType.StartObject)
+                            {
+                                throw new SerialisationException($"Unexpected token type after \"Columns\": {reader.TokenType}");
+                            }
+                            reader.Read(); // Skip over StartObject
+                            while (reader.TokenType != JsonTokenType.EndObject)
+                            {
+                                string name = reader.GetString()!;
+                                reader.Read(); // Advance to the property value
+                                var type = reader.GetString();
+                                result.Columns.Add(new CoreColumn { ColumnName = name, DataType = CoreUtils.GetEntity(type ?? "") });
+                                reader.Read(); // Move to next token
+                            }
+                            reader.Read(); // Skip EndObject
                         }
-                    }
-                    else if (propertyName == "Rows")
-                    {
-                        while (reader.TokenType != JsonTokenType.EndArray)
+                        else if (propertyName == "Rows")
                         {
-                            reader.Read();
-                            var iCol = 0;
-                            var newrow = result.NewRow();
+                            if(reader.TokenType != JsonTokenType.StartArray)
+                            {
+                                throw new SerialisationException($"Unexpected token type after \"Rows\": {reader.TokenType}");
+                            }
+                            reader.Read(); // Skip StartArray
                             while (reader.TokenType != JsonTokenType.EndArray)
                             {
-                                var col = result.Columns[iCol];
-                                reader.Read();
-                                newrow[col.ColumnName] = ReadJson(reader);
-                                iCol++;
+                                if(reader.TokenType != JsonTokenType.StartArray)
+                                {
+                                    throw new SerialisationException($"Unexpected token type: {reader.TokenType}");
+                                }
+                                reader.Read(); // Skip StartArray
+                                var iCol = 0;
+                                var newrow = result.NewRow();
+                                while (reader.TokenType != JsonTokenType.EndArray)
+                                {
+                                    var col = result.Columns[iCol];
+                                    newrow[col.ColumnName] = CoreUtils.ChangeType(ReadJson(reader), col.DataType);
+                                    reader.Read();
+                                    iCol++;
+                                }
+                                result.Rows.Add(newrow);
+                                reader.Read(); // Skip EndArray
                             }
-                            result.Rows.Add(newrow);
+                            reader.Read(); // Skip EndArray
                         }
                     }
                 }
             }
+            catch(SerialisationException e)
+            {
+                Logger.Send(LogType.Error, "", $"SerialisationException: {e.Message}");
+                return null;
+            }
             catch (Exception e)
             {
                 Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
@@ -95,9 +119,7 @@ namespace InABox.Core
         
         public override bool CanConvert(Type objectType)
         {
-            return typeof(CoreTable).GetTypeInfo().IsAssignableFrom(objectType);
+            return typeof(CoreTable).IsAssignableFrom(objectType);
         }
-
-
     }
 }

+ 11 - 1
InABox.Core/Serialization.cs

@@ -197,6 +197,8 @@ namespace InABox.Core
                 {
                     throw;
                 }
+
+                CoreUtils.LogException("", e);
                 if (typeof(T).IsArray)
                 {
                     ret = (T)(object)Array.CreateInstance(typeof(T).GetElementType(), 0);
@@ -889,6 +891,12 @@ namespace InABox.Core
             }
         }
         
+        /// <summary>
+        /// Write a value as a JSON object; note that some data types, like
+        /// <see cref="Guid"/> and <see cref="DateTime"/> will be encoded as
+        /// strings, and therefore will be returned as strings when read by
+        /// <see cref="ReadJson(Utf8JsonReader)"/>.
+        /// </summary>
         protected void WriteJson(Utf8JsonWriter writer, object? value)
         {
             if  (value == null)
@@ -905,9 +913,11 @@ namespace InABox.Core
                 writer.WriteNumberValue(dVal);
             else if (value is DateTime dtVal)
                 writer.WriteStringValue(dtVal.ToString());
+            else if (value is Guid guid)
+                writer.WriteStringValue(guid.ToString());
             else
             {
-                    
+                Logger.Send(LogType.Error, "", $"Could not write object of type {value.GetType()} as JSON");
             }
         }