c# - 在 .NET 数组内部绑定(bind) JSON 对象

标签 c# .net json marklogic

我有来自 MarkLogic 的 JSON 响应,我正在将其绑定(bind)到 C# 中的模型。相关片段如下:

{  
   "snippets":{  
      "match":[  
         {  
            "value":[  
               "In (consolidated) enforcement actions for failure to answer subpoena, appeal from ",
               {  
                  "highlight":{  
                     "value":"judgement"
                  }
               },
               " for defendants."
            ]
         }
      ]
   }
}

我遇到的问题是外部“值”数组,因为它包含两个字符串和另一个 JSON 对象。有什么方法可以在 C# 中绑定(bind)这个数组吗?我当前的模型如下所示:

[JsonProperty(PropertyName = "snippets")]
public MarkLogicSnippetsModel Snippets { get; set; }

public class MarkLogicSnippetsModel
{
    [JsonProperty(PropertyName = "match")]
    public IEnumerable<MarkLogicMatchModel> Matches { get; set; }
}

public class MarkLogicMatchModel
{
    [JsonProperty(PropertyName = "value")]
    public IEnumerable<string> Values { get; set; }
}

但是使用 IEnumerable<string>当数组中有对象时不起作用。

最佳答案

看起来 JSON 应该表示某个整体字符串中的匹配,在本例中是 In (consolidated) enforcement actions for failure to answer subpoena, appeal from judgement for defendants. 中字符串“judgement”的匹配。因此,您的数据模型将需要能够重建整个字符串,并挑选出匹配的部分。

假设 JSON 无法更改,我建议使用如下数据模型:

public class RootObject
{
    [JsonProperty(PropertyName = "snippets")]
    public MarkLogicSnippetsModel Snippets { get; set; }
}

public class MarkLogicSnippetsModel
{
    [JsonProperty(PropertyName = "match")]
    public IEnumerable<MarkLogicMatchModel> Matches { get; set; }
}

public class MarkLogicMatchModel
{
    [JsonProperty(PropertyName = "value")]
    public List<MarkLogicMatchEntry> Values { get; set; }
}

public enum MatchType
{
    Normal,
    Highlight,
}

[JsonConverter(typeof(MarkLogicMatchEntryConverter))]
public class MarkLogicMatchEntry
{
    public MatchType MatchType { get; set; }

    public string Value { get; set; }
}

使用以下转换器:

class MarkLogicMatchEntryConverter : JsonConverter
{
    JsonSerializer GetEnumSerializer()
    {
        return JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new[] { new StringEnumConverter { CamelCaseText = true } } });
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MarkLogicMatchEntry);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        else if (reader.TokenType == JsonToken.String)
        {
            return new MarkLogicMatchEntry { MatchType = MatchType.Normal, Value = reader.Value.ToString() };
        }
        else
        {
            var obj = JObject.Load(reader);
            var property = obj.Properties().FirstOrDefault();
            var type = ((JValue)property.Name).ToObject<MatchType>(GetEnumSerializer());
            var value = (string)property.Value.SelectToken("value");

            return new MarkLogicMatchEntry { MatchType = type, Value = value };
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var match = (MarkLogicMatchEntry)value;
        if (match.MatchType == MatchType.Normal)
        {
            writer.WriteValue(match.Value);
        }
        else
        {
            var propertyName = (string)JToken.FromObject(match.MatchType, GetEnumSerializer());
            var obj = new JObject(new JProperty(propertyName, new JObject(new JProperty("value", match.Value))));
            obj.WriteTo(writer);
        }
    }
}

这里搜索字符串的每个部分都由一个 MarkLogicMatchEntry 类表示。正常的、不匹配的子字符串用 MatchType = MatchType.Normal 表示。匹配的子字符串用 MatchType = MatchType.Highlight 表示。理论上,如果需要,可以添加其他匹配类型,例如 MatchType.Underline

关于c# - 在 .NET 数组内部绑定(bind) JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37950848/

相关文章:

c# - Jwt token 授权不起作用

c# - 如何使用 protobuf-net 处理 .proto 文件

.net - Array.Copy 与 Buffer.BlockCopy

.net - 如何在 Azure Pipeline 期间创建包含 build.* 变量的文件

.net - 有Windows Azure本地开发环境吗?

java - 序列化时如何创建虚拟 JSON 属性?

json - 将 JSON 中的数组嵌套到 CSV 中的不同行

c# - AuthCookie 已设置,仍被重定向到 login.aspx

c# - 为什么 JsonConvert 在反序列化为字典时抛出异常

javascript - 如何在javascript中检查对象中所有级别的对象是否为空