将包含字符串数组的 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字符串中,idlabel是由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