AnyType IDictionary serialize like JSON
Describe the bug
IDictionary<string, object> serialization as AnyType is weird.
To Reproduce
With the following query and output type
public class Query
{
public Thing Query() => new Thing { Junk = new Dictionary<string, object> {{ "name", "yo" }}};
}
public class Thing {
[GraphQLType(typeof(AnyType))] public IDictionary<string, object> Junk { get; set; }
}
An error is thrown EXEC_INVALID_LEAF_VALUE when querying.
If I change the dictionary type to IDictionary<string, string> then the serialization is weird
{
"junk": [
{
"key": "name",
"value": "yo"
}
]
}
If I create a constructor to take the dictionary<string, object> and iterate over its values calling ToString then I get the expected result and that is weird.
foreach(var key in Junk.Keys) {
Junk[key] = Junk[key].ToString();
}
But, I get the expected result
{
"junk": {
"name": "yo"
}
}
Expected behavior
I expect IDictionary<string, object> to serialize like json
Desktop (please complete the following information):
- OS: macos
- Version: 10.15.7
I'm also seeing this issue.
OS: macos Version: 11.3.0
I am as well.
Windows 10 Visual studio 2019 Version 11.3.0
partial record CountryDto
{
[GraphQLType(typeof(AnyType))]
public IDictionary<string, string> Provinces { get; init; } = null!;
}
Results in the following if I run the query in Banana Cake Pop
{
"data": {
"country": {
"name": "United States",
"abbreviation": "us",
"provinces": [
{
"key": "AL",
"value": "Alabama"
},
{
"key": "AK",
"value": "Alaska"
},
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Also faced this issue
I added this test:
[Fact]
public async Task Output_Return_Dictionary()
{
// arrange
ISchema schema = SchemaBuilder.New()
.AddQueryType(d => d
.Name("Query")
.Field("foo")
.Type<AnyType>()
.Resolve(_ => new Dictionary<string, object> {
{ "number", 123 },
{ "dateTime", DateTime.UnixEpoch } }))
.Create();
IRequestExecutor executor = schema.MakeExecutable();
// act
IExecutionResult result = await executor.ExecuteAsync("{ foo }");
// assert
result.ToJson().MatchSnapshot();
}
But the snapshot looks correct ...
{
"data": {
"foo": {
"number": 123,
"dateTime": "1970-01-01T00:00:00.000Z"
}
}
}
So I'm not sure what's going on in my case (and the case of the OP and others).
I'm using this in my Error type.
I need to look into it more.
Hello,
Do you think you will work on this subject ? I have to return yaml content files from my api (I parse the files and load them into Dictionary<string, object>) and need to have the capacity.
Maybe I found a workaround. Don't expose a Dictionary but a IReadOnlyDictionary as the AnyType ParseValue will do :
if (value is IReadOnlyDictionary<string, object> dict)
{
var fields = new List<ObjectFieldNode>();
foreach (var field in dict)
{
fields.Add(new ObjectFieldNode(
field.Key,
ParseValue(field.Value, set)));
}
return new ObjectValueNode(fields);
}
By changing my Dictionary type to IReadOnlyDictionary, I had the expected result
Before :
{
"capacities":[{"key":"SubnetProvider","value":true}]
}
After :
{
"capacities":{"SubnetProvider":true}
}
thank you
I have same error and the workaround exposing the Dictionary as IReadOnlyDictionary it doesn't work in my case, I'm still getting key/value pairs.
The same thing happens to me, even after changing to IReadOnlyDictionary.
Trying to debug this a bit, and for whatever reason, the runtime type is a KeyValuePair – that seems odd, shouldn't it be a dictionary?

A dictionary is basically ICollection<KeyValuePair<K,V>>.
A dictionary is basically
ICollection<KeyValuePair<K,V>>.
Right, but KeyValuePair is the element type, not the type itself.
Use our new JsonType. Video coming out soon ...
@michaelstaib
Use our new JsonType. Video coming out soon ...
If I do ...
[GraphQLType<JsonType>]
public required Dictionary<string, string> Fields { get; init; }
I get:
JSON cannot serialize the given value.
I don't think that the JSON type solves the original issue of serializing dictionaries specifically, not just any dynamic data.
If JSON serializes a Dictionary<string, object> (or <string, string>) as an object/map, one might expect that to be the default behaviour in Hot Chocolate.
I have reopened this to investigate the issue @glen-84 still has with the Any and JSON.
I tested the issue in the OP, and I cannot reproduce it in HC 13.0.2.
Michael has said that only <string, object> is supported, not <string, string>.
@RubcovMindbox @ernestfolch @corinaivanov
Which type and generic arguments are you using?
I encountered similar issue.
Returning type
public record MyObjectState
{
public string Id {get; set; }
[GraphQLType(typeof(AnyType))]
public IDictionary<string, object?>? Fields { get; set; }
}
GraphQL
myObject(
id: "cool-guid") {
id
fields
}
MongoDB Database content
{
"_id": "cool-guid",
"fields": {
"name": "MyName",
"someOptionalValue": null,
"someStringValue": "32",
"dateOfBirth": {
"$date": "2023-04-05T00:00:00.000Z"
},
"gender": "female",
"nestedObject": {},
"nestedArray": [
{
"name": "item1",
"isOk": true,
"rules": [
{
"node": "abra kadabra"
}
],
"dataFields": [
"dateOfBirth",
"name"
]
},
{
"name": "item2",
"isOk": true,
"rules": [
{
"description": "hehe < 5"
}
],
"dataFields": [
"dateOfBirth",
"someStringValue"
]
}
],
"someCode": {
"$numberLong": "0"
}
},
}
Error
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 19,
"column": 3
}
],
"path": [
"myObject",
"fields"
],
"extensions": {
"message": "Parameter count mismatch.",
"stackTrace": " at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.Convert(Object obj)\n at HotChocolate.Types.AnyType.TrySerialize(Object runtimeValue, Object& resultValue)\n at HotChocolate.Types.ScalarType.Serialize(Object runtimeValue)\n at HotChocolate.Execution.Processing.ValueCompletion.TryCompleteLeafValue(IOperationContext operationContext, MiddlewareContext resolverContext, ISelection selection, Path path, IType fieldType, Object result, Object& completedResult)",
"code": "EXEC_INVALID_LEAF_VALUE",
"remote": {
"message": "Unexpected Execution Error",
"locations": [
{
"line": 1,
"column": 172
}
],
"path": [
"myObject",
"fields"
],
"extensions": {
"message": "Parameter count mismatch.",
"stackTrace": " at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitList(ICollection list, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitObject(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.VisitValue(Object obj, Action`1 setValue, ISet`1 processed)\n at HotChocolate.Utilities.ObjectToDictionaryConverter.Convert(Object obj)\n at HotChocolate.Types.AnyType.TrySerialize(Object runtimeValue, Object& resultValue)\n at HotChocolate.Types.ScalarType.Serialize(Object runtimeValue)\n at HotChocolate.Execution.Processing.ValueCompletion.TryCompleteLeafValue(IOperationContext operationContext, MiddlewareContext resolverContext, ISelection selection, Path path, IType fieldType, Object result, Object& completedResult)",
"code": "EXEC_INVALID_LEAF_VALUE"
}
},
"schemaName": "mySchemaName"
}
}
],
"data": {
"myObject": {
"id": "cool-guid",
"fields": null
}
}
}
For me it was JToken and ExpandoObject issues.
I had to convert JToken to Dictionary recursively instead of just using .ToObject<Dictionarty<string, object?>>
And I had to convert ExpandoObject to ReadOnlyDictionary. It's a dictionary already, but it seems HC expects only ReadOnly ones in ObjectToDictionaryConverter

@michaelstaib Does it make sense to add IDictionary in addition to IReadOnlyDictionary in ObjectToDictionaryConverter?
private void VisitObject(
object obj,
Action<object> setValue,
ISet<object> processed)
{
if (processed.Add(obj))
{
var dict = new Dictionary<string, object>();
setValue(dict);
if (obj is IReadOnlyDictionary<string, object> d)
{
foreach (KeyValuePair<string, object> item in d)
{
Action<object> setField = v => dict[item.Key] = v;
VisitValue(item.Value, setField, processed);
}
}
else
{
foreach (PropertyInfo property in GetProperties(obj))
{
string name = property.GetGraphQLName();
object value = property.GetValue(obj);
Action<object> setField = v => dict[name] = v;
VisitValue(value, setField, processed);
}
}
}
}
I have moved this to 13.4 to refine the Any type further.