将包含字符串数组的 Gremlin 结果映射到包含简单字符串属性的 C# class
Map Gremlin result containing string arrays to C# class containing simple string properties
我在将 Gremlin 结果集映射到 C# 中的 class 时遇到问题。我正在尝试获取顶点和属性。这是代码:
public IList<T> All<T>() where T : class, new()
{
Type type = typeof(T);
string query = "g.V().hasLabel('" + type.Name.ToString().ToLower() + "').valueMap(true)";
var resultSet = _gremlinClient.SubmitAsync<dynamic>(query).Result;
List<T> list = JsonConvert.DeserializeObject<List<T>>(JsonConvert.SerializeObject(resultSet));
return list;
}
这里是我传递给这个通用方法的用户实体。
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
当我 运行 代码时,它在反序列化时抛出错误。
'Unexpected character encountered while parsing value: [. Path '[0].FirstName', line 1, position 37.'
当我检查它时,我发现 JSON 字符串有带方括号的 属性 值,像这样:
[
{
"id": 0,
"label": "user",
"FirstName": [ "Azhar" ],
"LastName": [ "Rahi" ]
},
{
"id": 3,
"label": "user",
"FirstName": [ "John" ],
"LastName": [ "Doe" ]
}
]
您可以看到一些属性带有方括号,例如 "FirstName":["Azhar"]
。我已经在没有方括号的情况下对其进行了测试,并且工作正常。所以错误的原因是因为字符串在 JSON.
中表示为数组
在上面的JSON字符串中,id
和label
是由Gremlin.Net自动生成的属性。其余的实际上是 User
对象属性。我不知道为什么 Gremlin 在向 Vertex
添加属性时添加括号,以及是否有可能避免它。
请提出任何解决方案,在 Gremlin.Net 中或通过某种方式将 JSON 的映射更改为 class。
所以,回顾一下:您有一些 JSON,其中一些属性是字符串数组,但您想在 类 中将它们建模为单个字符串,因为数组应该始终只有一个值。
如您所见,Json.Net 默认情况下不会处理此映射。但是您可以使用自定义 JsonConverter
来弥合差距。像这样定义转换器:
public class ArrayToSingleStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
switch (token.Type)
{
case JTokenType.Array:
return (string)token.Children<JValue>().FirstOrDefault();
case JTokenType.String:
return (string)token;
case JTokenType.Null:
return null;
default:
throw new JsonException("Unexpected token type: " + token.Type);
}
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后,对于 类 中的每个字符串 属性(可能是 JSON 中的数组),添加一个 [JsonConverter]
属性指定 ArrayToSingleStringConverter
,像这样:
public class User
{
[JsonConverter(typeof(ArrayToSingleStringConverter))]
public string FirstName { get; set; }
[JsonConverter(typeof(ArrayToSingleStringConverter))]
public string LastName { get; set; }
}
当您反序列化 JSON 时,它现在应该可以正常工作了。
演示 fiddle:https://dotnetfiddle.net/Q9sGja
注意:如果您想以这种方式处理 所有 字符串属性,您可以将转换器传递给 JsonConvert.DeserializeObject()
而不是标记 [=42] =] 具有 [JsonConverter]
个属性:
List<T> list = JsonConvert.DeserializeObject<List<T>>(json, new ArrayToSingleStringConverter());
Fiddle: https://dotnetfiddle.net/gcAqC5
我在将 Gremlin 结果集映射到 C# 中的 class 时遇到问题。我正在尝试获取顶点和属性。这是代码:
public IList<T> All<T>() where T : class, new()
{
Type type = typeof(T);
string query = "g.V().hasLabel('" + type.Name.ToString().ToLower() + "').valueMap(true)";
var resultSet = _gremlinClient.SubmitAsync<dynamic>(query).Result;
List<T> list = JsonConvert.DeserializeObject<List<T>>(JsonConvert.SerializeObject(resultSet));
return list;
}
这里是我传递给这个通用方法的用户实体。
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
当我 运行 代码时,它在反序列化时抛出错误。
'Unexpected character encountered while parsing value: [. Path '[0].FirstName', line 1, position 37.'
当我检查它时,我发现 JSON 字符串有带方括号的 属性 值,像这样:
[
{
"id": 0,
"label": "user",
"FirstName": [ "Azhar" ],
"LastName": [ "Rahi" ]
},
{
"id": 3,
"label": "user",
"FirstName": [ "John" ],
"LastName": [ "Doe" ]
}
]
您可以看到一些属性带有方括号,例如 "FirstName":["Azhar"]
。我已经在没有方括号的情况下对其进行了测试,并且工作正常。所以错误的原因是因为字符串在 JSON.
在上面的JSON字符串中,id
和label
是由Gremlin.Net自动生成的属性。其余的实际上是 User
对象属性。我不知道为什么 Gremlin 在向 Vertex
添加属性时添加括号,以及是否有可能避免它。
请提出任何解决方案,在 Gremlin.Net 中或通过某种方式将 JSON 的映射更改为 class。
所以,回顾一下:您有一些 JSON,其中一些属性是字符串数组,但您想在 类 中将它们建模为单个字符串,因为数组应该始终只有一个值。
如您所见,Json.Net 默认情况下不会处理此映射。但是您可以使用自定义 JsonConverter
来弥合差距。像这样定义转换器:
public class ArrayToSingleStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
switch (token.Type)
{
case JTokenType.Array:
return (string)token.Children<JValue>().FirstOrDefault();
case JTokenType.String:
return (string)token;
case JTokenType.Null:
return null;
default:
throw new JsonException("Unexpected token type: " + token.Type);
}
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后,对于 类 中的每个字符串 属性(可能是 JSON 中的数组),添加一个 [JsonConverter]
属性指定 ArrayToSingleStringConverter
,像这样:
public class User
{
[JsonConverter(typeof(ArrayToSingleStringConverter))]
public string FirstName { get; set; }
[JsonConverter(typeof(ArrayToSingleStringConverter))]
public string LastName { get; set; }
}
当您反序列化 JSON 时,它现在应该可以正常工作了。
演示 fiddle:https://dotnetfiddle.net/Q9sGja
注意:如果您想以这种方式处理 所有 字符串属性,您可以将转换器传递给 JsonConvert.DeserializeObject()
而不是标记 [=42] =] 具有 [JsonConverter]
个属性:
List<T> list = JsonConvert.DeserializeObject<List<T>>(json, new ArrayToSingleStringConverter());
Fiddle: https://dotnetfiddle.net/gcAqC5