diff --git a/libraries/Microsoft.Bot.Schema/Converters/AttachmentMemoryStreamConverter.cs b/libraries/Microsoft.Bot.Schema/Converters/AttachmentMemoryStreamConverter.cs
index 8667bd215f..79676a54b6 100644
--- a/libraries/Microsoft.Bot.Schema/Converters/AttachmentMemoryStreamConverter.cs
+++ b/libraries/Microsoft.Bot.Schema/Converters/AttachmentMemoryStreamConverter.cs
@@ -61,7 +61,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
reader.Read();
}
- if (HaveStreams(list))
+ if (HasMemoryStream(list))
{
return list;
}
@@ -103,8 +103,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
dict.Add(key, item);
}
- var list = dict.Values.ToList();
- if (HaveStreams(list))
+ if (HasMemoryStream(dict))
{
return dict;
}
@@ -119,68 +118,139 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
- if (!typeof(MemoryStream).IsAssignableFrom(value.GetType()))
+ if (HasMemoryStream(value))
{
- if (value.GetType().GetInterface(nameof(IEnumerable)) != null)
+ InternalWriteJson(writer, value, serializer);
+ return;
+ }
+
+ JToken.FromObject(value, serializer).WriteTo(writer);
+ }
+
+ private static void InternalWriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ if (value == null || value is string)
+ {
+ // Avoid processing strings, since they implement IEnumerable.
+ JToken.FromObject(value, serializer).WriteTo(writer);
+ return;
+ }
+
+ if (value is MemoryStream)
+ {
+ var buffer = (value as MemoryStream).ToArray();
+ var result = new SerializedMemoryStream
+ {
+ Type = nameof(MemoryStream),
+ Buffer = buffer.ToList()
+ };
+
+ JToken.FromObject(result, serializer).WriteTo(writer);
+ return;
+ }
+
+ if (value is IDictionary dictionary)
+ {
+ writer.WriteStartObject();
+ foreach (DictionaryEntry entry in dictionary)
{
- // This makes the WriteJson loops over nested values to replace all instances of MemoryStream.
- serializer.Converters.Add(this);
+ writer.WritePropertyName(entry.Key.ToString());
+ InternalWriteJson(writer, entry.Value, serializer);
}
- JToken.FromObject(value, serializer).WriteTo(writer);
- serializer.Converters.Remove(this);
+ writer.WriteEndObject();
+ return;
+ }
+
+ if (value is IEnumerable collection)
+ {
+ writer.WriteStartArray();
+ foreach (var item in collection)
+ {
+ InternalWriteJson(writer, item, serializer);
+ }
+
+ writer.WriteEndArray();
return;
}
- var buffer = (value as MemoryStream).ToArray();
- var result = new SerializedMemoryStream
+ var type = value.GetType();
+ if (type.IsClass)
{
- Type = nameof(MemoryStream),
- Buffer = buffer.ToList()
- };
+ writer.WriteStartObject();
+ foreach (var prop in type.GetProperties())
+ {
+ writer.WritePropertyName(prop.Name);
+ InternalWriteJson(writer, prop.GetValue(value), serializer);
+ }
- JToken.FromObject(result).WriteTo(writer);
+ writer.WriteEndObject();
+ return;
+ }
+
+ JToken.FromObject(value, serializer).WriteTo(writer);
}
///
- /// Check if a List contains at least one MemoryStream.
+ /// Check if an object contains at least one MemoryStream.
///
- /// List of values that might have a MemoryStream instance.
+ /// Object contaning values that might have a MemoryStream instance.
/// True if there is at least one MemoryStream in the list, otherwise false.
- private static bool HaveStreams(List