如何反序列化具有动态(数字)键名的子对象?如何在.net中使用newtonsoftjson.net反序列化json结构。{“users”:{“parentname”:“test”,“100034”:{“name”:“tom”,“state”:“WA”,“id”:“cedf-c56f-18a4-4b1”},“10045”:{“名称”:“史蒂夫”,“州”:“纽约”,“id”:“ebb2-92bf-3062-7774”},“12345”:{“名称”:“迈克”,“state":"MA","id":"fb60-b34f-6dc8-aaf7"}}}我尝试了下面的代码,但它不起作用。我收到错误消息“将值‘test’转换为类型‘ConsoleApplication2.User’时出错”。路径“users.parentname”,第5行,位置35。'classProgram{staticvoidMain(string[]args){stringjson=@"{""users"":{""parentname"":""test"",""10045"":{""name"":""史蒂夫"",""state"":""NY"",""id"":""ebb2-92bf-3062-7774""}}}";RootObjectroot=JsonConvert.DeserializeObject(json);}}classRootObject{publicstringParentName{get;放;}publicDictionaryusers{get;放;}}classUser{公共字符串名称{get;放;}公共字符串状态{得到;放;}publicstringid{get;放;}publicstringParentName{get;放;}}请建议。您有几个问题:以下转换器允许将未知属性反序列化为类型化容器,而不是任意类型的字典:[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property,AllowMultiple=false)]:JsonConverter{publicoverrideboolCanConvert(TypeobjectType){returntypeof(TObject).IsAssignableFrom(objectType);}JsonPropertyGetExtensionJsonProperty(JsonObjectContractcontract){try{returncontract.Properties.Werb>trib>.GetAttributes(typeof(JsonTypedExtensionDataAttribute),false).Any()).Single();}catch(InvalidOperationExceptionex){thrownewJsonSerializationException(string.Format("类型{0}需要一个具有JsonTypedExtensionDataAttribute的属性",contract.UnderlyingType),ex);}}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){if(reader.TokenType==JsonToken.Null)返回n空;varjObj=JObject.Load(阅读器);varcontract=(JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType);varextensionJsonProperty=GetExtensionJsonProperty(合同);varextensionJProperty=(JProperty)null;对于(inti=jObj.Count-1;i>=0;i--){varproperty=(JProperty)jObj.AsList()[i];if(contract.Properties.GetClosestMatchProperty(property.Name)==null){if(extensionJProperty==null){extensionJProperty=newJProperty(extensionJsonProperty.PropertyName,newJObject());jObj.Add(extensionJProperty);}((JObject)extensionJProperty.Value).Add(property.RemoveFromLowestPossibleParent());}}变量值=existingValue??contract.DefaultCreator();使用(varsubReader=jObj.CreateReader())serializer.Populate(subReader,value);返回值;}publicoverridevoidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){varcontract=(JsonObjectContract)serializer.ContractResolver.Resolve合同(价值。GetType());varextensionJsonProperty=GetExtensionJsonProperty(合同);J对象使用(newPushValue(true,()=>Disabled,(canWrite)=>Disabled=canWrite)){jObj=JObject.FromObject(value,serializer);}varextensionValue=(jObj[extensionJsonProperty.PropertyName]asJObject).RemoveFromLowestPossibleParent();如果(extensionValue!=null){for(inti=extensionValue.Count-1;i>=0;i--){varproperty=(JProperty)extensionValue.AsList()[i];jObj.Add(property.RemoveFromLowestPossibleParent());}}jObj.WriteTo(作家);}[ThreadStatic]静态布尔禁用;//以线程安全的方式禁用转换器。布尔禁用{得到{返回禁用;}设置{禁用=值;}}publicoverrideboolCanWrite{get{return!Disabled;}}publicoverrideboolCanRead{get{return!Disabled;}}}publicstructPushValue:IDisposable{ActionsetValue;旧值;publicPushValue(Tvalue,FuncgetValue,ActionsetValue){if(getValue==null||setValue==null)thrownewArgumentNullException();this.setValue=setValue;this.oldValue=getValue();设置值(值);}#regionIDisposableMembers//通过使用一次性结构,我们避免了分配和释放可终结类实例的开销。publicvoidDispose(){if(setValue!=null)setValue(oldValue);}#endregion}publicstaticclassJsonExtensions{publicstaticTJTokenRemoveFromLowestPossibleParent(thisTJTokennode)whereTJToken:JToken{if(node==null)returnnull;varcontained=node.AncestorsAndSelf().Where(t=>t.ParentisJContainer&&t.Parent.Type!=JTokenType.Property).FirstOrDefault();if(contained!=null)contained.Remove();//同时将节点与其直接包含的属性分离——Remove()不会执行此操作,即使它看起来应该执行此操作if(node.ParentisJProperty)((JProperty)node.Parent).Value=null;返回节点;}公共静态IListAsList(这个IList容器){返回容器;然后像这样在你的类中使用它:classRootObject{[JsonProperty("users")]publicUsersUsers{get;放;}}[JsonConverter(typeof(TypedExtensionDataConverter))]classUsers{publicUsers(){this.UserTable=newDictionary();}[JsonProperty("parentname")]publicstringParentName{get;放;}[JsonTypedExtensionData]publicDictionaryUserTable{get;放;}}classUser{公共字符串名称{get;放;}公共字符串状态{得到;放;}publicstringid{get;用户类型的硬编码转换器将需要更少的代码。您的Json必须如下所示:{"ParentName":"test","users":{"10045":{"name":"steve","state":"NY","id":"ebb2-92bf-3062-7774","ParentName":"someOtherName"}}}为了用给定的类结构反序列化它:classRootObject{publicstringParentName{get;放;}publicDictionaryusers{get;放;}}classUser{公共字符串名称{get;放;}公共字符串状态{得到;放;}publicstringid{get;放;}publicstringParentName{get;放;现在你可以使用如下命令反序列化Json字符串:以上是C#学习教程:Howtodeserializesub-objectswithdynamic(numeric)keynames?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——varroot=JsonConvert.DeserializeObject(json);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
