我有来自 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/