我正在尝试将字符串内容反序列化为对象,但我希望内容区分大小写。代码应仅在字符串具有小写属性时成功,如果具有大写属性则失败。以下是课程:
internal class ResponseList
{
[DataMember]
[JsonProperty]
internal List<Response> Value { get; set; }
}
internal class Response
{
[DataMember]
[JsonProperty]
internal string Id { get; set; }
[DataMember]
[JsonProperty]
internal string Location { get; set; }
[DataMember]
[JsonProperty]
internal PlanClass Plan { get; set; }
}
internal class PlanClass
{
[DataMember]
[JsonProperty]
internal string Name { get; set; }
[DataMember]
[JsonProperty]
internal string Product { get; set; }
[DataMember]
[JsonProperty]
internal string Publisher { get; set; }
}
以下是我的代码。但这不区分大小写。大写和小写都是成功的:
string content = File.ReadAllText(contentFilePath);
JsonSerializerSettings jsonSerializerSettings1 = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
ResponseList response = (ResponseList)JsonConvert.DeserializeObject(contentResourceOutput, typeof(ResponseList), Constants.JsonSerializerSettings);
只有在内容为:
时,代码才能成功{
"value": [
{
"id": "id1",
"location": "location1",
"plan": {
"name": "free",
"product": "product1",
"publisher": "publisher1"
}
}
]
}
并且即使其中一个键是大写的也会失败。例如。
{
"value": [
{
"Id": "id1",
"Location": "location1",
"plan": {
"Name": "free",
"product": "product1",
"publisher": "publisher1"
}
}
]
}
请注意,只有Keys / Property名称应为小写。值可以是大写。 有没有办法让JsonConvert.Deserializeobject区分大小写?
答案 0 :(得分:3)
您可以编写自定义转换器来处理此用例。关于您对所有关键名称进行递归检查的需求,我使用了Thymine here给出的精彩WalkNode
答案。
var json = @"{""id"": ""id1"",""name"": ""name1"",""type"": ""type1""}";
var json2 = @"{""id"": ""id1"",""Name"": ""name1"",""type"": ""type1""}";
JsonSerializerSettings settings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter> { new CamelCaseOnlyConverter() }
};
var response = JsonConvert.DeserializeObject<Response>(json, settings);
var response2 = JsonConvert.DeserializeObject<Response>(json2, settings);
public class CamelCaseOnlyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = (JObject)JToken.Load(reader);
var isCamelCased = true;
WalkNode(token, null,
t =>
{
var nameFirstChar = t.Name[0].ToString();
if (!nameFirstChar.Equals(nameFirstChar.ToLower(),
StringComparison.CurrentCulture))
{
isCamelCased = false;
return;
}
});
if (!isCamelCased) return null;
return token.ToObject(objectType);
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
JObject o = (JObject)JToken.FromObject(value);
o.WriteTo(writer);
}
private static void WalkNode(JToken node,
Action<JObject> objectAction = null,
Action<JProperty> propertyAction = null)
{
if (node.Type == JTokenType.Object)
{
if (objectAction != null) objectAction((JObject)node);
foreach (JProperty child in node.Children<JProperty>())
{
if (propertyAction != null) propertyAction(child);
WalkNode(child.Value, objectAction, propertyAction);
}
}
else if (node.Type == JTokenType.Array)
foreach (JToken child in node.Children())
WalkNode(child, objectAction, propertyAction);
}
}
第一个字符串将返回一个水合物体。第二个字符串将提前终止,返回null。