当前位置: 首页 > 编程语言 > C#

如何反序列化同一对象中具有重复属性名的JSONShare

时间:2023-04-10 15:16:08 C#

如何反序列化同一对象中具有重复属性名的JSONJSON.NET快乐。我想知道是否有人知道在看到重复的键名时让JArrays将JObject的子JObjects转换为JArrays的最佳方法(也许使用JsonConverter?)?//例如:这给了我一个带有单个“JPropertyJObject”子对象的JObject。varobj=JsonConvert.DeserializeObject("{"HiThere":1}");//这会抛出://System.ArgumentException:无法将Newtonsoft.Json.Linq.JValue添加到Newtonsoft.Json.Linq.JObject.obj=JsonConvert.DeserializeObject("{"HiThere":1,"HiThere":2,“你好”:3}“);我正在尝试反序列化实际的JSON要复杂得多,并且重复项嵌套在多个级别。但是上面的代码显示了它失败的原因。我知道JSON是不正确的,这就是为什么我要问JSON.NET是否有办法解决这个问题。为了争论,让我说我无法控制JSON。我实际上正在为父对象使用特定类型,但我在处理将是字符串或另一个嵌套JSON对象的特定属性时遇到了问题。因此,失败的属性类型是“对象”。有趣的问题。我玩了一会儿,发现虽然JObject不能包含具有重复名称的属性,但在反序列化期间用于填充它的JsonTextReader没有这样的限制。(如果您考虑一下,这是有道理的:它是一个只读的阅读器;它不关心过去读过什么)。有了这些知识,我开始编写一些代码来填充JTokens的层次结构,如果在特定JObject中遇到重复的属性名称,则根据需要将属性值转换为JArray。由于我不知道您的实际JSON和要求,您可能需要稍微调整一下,但至少从一开始就是这样。这是代码:publicstaticJTokenDeserializeAndCombineDuplicates(JsonTextReaderreader){if(reader.TokenType==JsonToken.None){reader.Read();}if(reader.TokenType==JsonToken.StartObject){reader.Read();JObjectobj=newJObject();while(reader.TokenType!=JsonToken.EndObject){stringpropName=(string)reader.Value;读者。阅读();JTokennewValue=DeserializeAndCombineDuplicates(阅读器);JTokenexistingValue=obj[propName];if(existingValue==null){obj.Add(newJProperty(propName,newValue));}elseif(existingValue.Type==JTokenType.Array){CombineWithArray((JArray)existingValue,newValue);}else//将现有的非数组属性值转换为数组{JPropertyprop=(JProperty)existingValue.Parent;JArray数组=newJArray();prop.Value=数组;array.Add(existingValue);CombineWithArray(数组,新值);}reader.Read();}返回对象;}if(reader.TokenType==JsonToken.StartArray){reader.Read();JArray数组=新J大批();while(reader.TokenType!=JsonToken.EndArray){array.Add(DeserializeAndCombineDuplicates(reader));读者。阅读();}返回数组;}返回新的JValue(reader.Value);}privatestaticvoidCombineWithArray(JArrayarray,JTokenvalue){if(value.Type==JTokenType.Array){foreach(JTokenchildinvalue.Children())array.Add(child);}else{array.Add(value);}}这是一个演示:classProgram{staticvoidMain(string[]args){stringjson=@"{""Foo"":1,""Foo"":[2],""Foo"":[3,4],""Bar"":{""X"":[""A"",""B""]},""Bar"":{""X"":""C"",""X"":""D""},}";使用(StringReadersr=newStringReader(json))使用(JsonTextReaderreader=newJsonTextReader(sr)){JTokentoken=DeserializeAndCombineDuplicates(reader);转储(令牌,“”);}}privatestaticvoidDump(JTokentoken,stringindent){Console.Write(indent);if(token==null){Console.WriteLine("null");返回;}Console.Write(token.Type);如果(令牌是JProperty)Cconsole.Write("(name="+((JProperty)token).Name+")");elseif(tokenisJValue)Console.Write("(value="+token.ToString()+")");控制台.WriteLine();if(token.HasValues)foreach(JTokenchildintoken.Children())Dump(child,indent+"");}}输出:对象属性(name=Foo)ArrayInteger(value=1)Integer(value=2)Integer(value=3)Integer(value=4)Property(name=Bar)ArrayObjectProperty(name=X)ArrayString(value=A)String(value=B)ObjectProperty(name=X)ArrayString(value=C)String(value=D)BrianRogers-这是JsonConverter的辅助函数,我根据你的评论JsonTextReader如何只是一个前向阅读器而不关心重复值修改。privatestaticobjectGetObject(JsonReaderreader){switch(reader.TokenType){caseJsonToken.StartObject:{vardictionary=newDictionary();while(reader.Read()&&(reader.TokenType!=JsonToken.EndObject)){if(reader.TokenType!=JsonToken.PropertyName)thrownewInvalidOperationException("UnknownJObjectconversionstate");}字符串propertyName=(string)reader.Value;读者。阅读();objectpropertyValue=GetObject(读者);对象存在值;if(dictionary.TryGetValue(propertyName,outexistingValue)){if(existingValueisList){varlist=existingValueasList;list.Add(propertyValue);}else{varlist=newList{existingValue,propertyValue};字典[属性名称]=列表;}}else{dictionary.Add(propertyName,propertyValue);}}返回字典;}caseJsonToken.StartArray:{varlist=newList();while(reader.Read()&&(reader.TokenType!=JsonToken.EndArray)){objectpropertyValue=GetObject(reader);list.Add(propertyValue);}返回列表;}默认值:{returnreader.Value;你不应该使用通用类型对象,它应该是更具体的类型但是你的json格式不正确,这是你的主要问题:“{“HiThere”:1,“HiThere”:2,“HiThere”:3}"但它应该是:"{"HiThere":[{"HiThere":1},{"HiThere"":2},{"HiThere":3}]}"或"{"HiThereOne":1,"HiThereTwo":2,"HiThereThree":3}"你的json是一个包含3个同名对象("HiThere")的字段的json。这是行不通的。我展示的json给出:一个数组三个对象(HiTheres),每个对象都有一个HiThere或One对象的字段,其中三个字段有不同的名字。(HiThereOne,HiThereTwo,“HiThereThree”)看看http://jsoneditoronline.org/index.html和http://json.org/以上是C#学习教程:Howtodeserializewithrepeatedpropertynamesinthesameobject如果JSON分享的所有内容对你有用,你需要进一步了解C#学习教程,希望大家多多关注,本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: