JsonConvert.DeserializeObject(string)returnsnullvaluefor$idproperty我正在使用System.Net.WebClient.DownloadString下载JSON。我收到了有效回复:{"FormDefinition":[{"$id":"4","Class":558,"ClassDisplayLabel":"Punchworks","Name":"PunchworksForm"},{"$id":"6","Class":558,"ClassDisplayLabel":"Punchworks","Name":"PunchworksFormtestsecond"},{"$id":"46","Class":558,"ClassDisplayLabel":"Punchworks","Name":"any_Name"},{"$id":"47","Class":558,"ClassDisplayLabel":"Punchworks","Name":"PunchworksFormtestsecond"},{"$id":"49","Class":558,"ClassDisplayLabel":"Punchworks","Name":"测试名称??′??????????ACEei??uu{[(~!@#"},{"$id":"50","Class":558,"ClassDisplayLabel":"Punchworks","Name":"somethingnew"},{"$id":"56","Class":558,"ClassDisplayLabel":"Punchworks","Name":"测试名称(~!@#"},{"$id":"57","Class":558,"ClassDisplayLabel":"Punchworks","Name":"测试名称"},{"$id":"58","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/201312:59:29PM"},{"$id":"59","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:01:18PM"},{"$id":"60","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:40:44PM"},{"$id":"61","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:43:46PM"},{"$id":"62","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:48:21PM"},{"$id":"63","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:57:00PM"},{"$id":"64","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:57:53PM"},{"$id":"65","Class":558,"ClassDisplayLabel":"Punchworks","Name":"UniqueName-12/16/20131:58:46PM"},{"$id":"79","Class":558,"ClassDisplayLabel":"Punchworks","Name":"TestingName1211"},{"$id":"80","Class":558,"ClassDisplayLabel":"Punchworks","Name":"TestingName1211"},{"$id":"81","Class":5个58、“ClassDisplayLabel”:“Punchworks”,“Name”:“any_nami”},{“$id”:“90”,“Class”:558,“ClassDisplayLabel”:“Punchworks”,“Name”:“Test_something3”},{"$id":"91","Class":558,"ClassDisplayLabel":"Punchworks","Name":"Test_something4"}]}这是我的模型:publicclassFormDefinitionList{[JsonProperty("FormDefinition")]公共列表FormDefinitions{get;放;}}publicclassFormDefinition{[JsonProperty(“$id”)]publicstringId{get;放;}[JsonProperty(“Class”)]publicintClass{get;放;}[JsonProperty("ClassName")]publicstringClassName{get;放;}[JsonProperty("ClassDisplayLabel")]publicstringClassDisplayLabel{get;放;}[JsonProperty("Definition")]publicstringDefinition{get;放;}[JsonProperty("Name")]publicstringName{get;放;我所做的一切都有效:stringresponse="jsonasabove";FormDefinitionListroot=JsonConvert.DeserializeObject(响应);除了Id($id)属性始终为null起初我试图弄清楚我从服务器返回的美元符号是不同的,但事实并非如此。我不知道从哪里开始,有什么想法吗?提前致谢。注意:如果我尝试使用JavaScriptSerializer之类的东西进行反序列化,它会完美地工作,所以我很确定我的模型或JSON.net有问题。可能是错的。Json.Net通常使用$id和$ref作为元数据来保存JSON中的对象引用。因此,当它看到$id时,它假定该属性不是实际JSON属性集的一部分,而是一个内部标识符。因此,它不会填充对象的Id属性,即使您包含指示它应该包含的[JsonProperty]属性。更新从Json.Net版本6.0.4开始,有一个新设置指示反序列化器将这些“元数据”属性视为普通属性,而不是使用它们。您需要做的就是将MetadataPropertyHandling设置为Ignore,然后像往常一样反序列化。varsettings=newJsonSerializerSettings();settings.MetadataPropertyHandling=MetadataPropertyHandling.Ignore;varobj=JsonConvert.DeserializeObject(json,设置);在版本6.0.4之前,需要一种解决方法来解决此问题。该答案的其余部分讨论了可能的解决方法。如果您使用的是6.0.4或更高版本,则不需要解决方法,现在可以停止阅读。正如@CarlosCoelho所建议的,我能看到的最简单的修复方法是在反序列化之前将JSON上的“$id”替换为“id”(包括引号)。由于您必须为每个响应执行此操作,如果您走这条路,我建议您使用简单的辅助方法来避免代码重复,例如:publicstaticTDeserialize(stringjson){returnJsonConvert.DeserializeObject(json.Replace(""$id"",""id""));但是,既然你在评论中说你不那么热衷于使用字符串替换的想法,我将研究其他选项。我为您找到了另一种可能的JsonConverter替代方案-自定义JsonConverter。转换器背后的想法是,它将尝试使用Json.Net的内置反序列化机制来创建和填充对象(没有ID),然后从JSON中手动检索$id属性并使用它来填充Id属性通过反射的对象。下面是转换器的代码:}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializer){JObjectjo=JObject.Load(reader);对象o=jo.ToObject(objectType);JTokenid=jo["$id"];if(id!=null){PropertyInfoprop=objectType.GetProperty("Id");if(prop!=null&&prop.CanWrite&&prop.PropertyType==typeof(string)){prop.SetValue(o,id.ToString(),null);}}返回o;}publicoverridevoidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){thrownewNotImplementedException();我尝试编写转换器,以便它适用于任何具有$id的对象——你只需要相应地更改CanConvert方法,这样除了FormDefinition之外,FormDefinition还需要为所有使用它的类型返回true。要使用转换器,只需将其实例传递给DeserializeObject,如下所示:FormDefinitionListroot=JsonConvert.DeserializeObject(json,newDollarIdPreservingConverter());重要说明:您可能想用JsonConverter属性装饰类,而不是将转换器传递给DeserializeObject调用,但不要这样做——这将导致转换器进入递归循环,直到堆栈溢出。(有一种方法可以让转换器使用该属性,但您必须重写ReadJson方法以手动创建目标对象并填充其属性,而不是调用jo.ToObject(objectType)。这可行,但更多麻烦。)如果这让我知道它是否适合你。问题是$符号,所以解决方案是:从JsonProperty注释中删除$。[JsonProperty("id")]publicstringId{get;放;在您的代码中,替换特殊字符$stringresponse="jsonasabove";FormDefinitionListroot=JsonConvert.DeserializeObject(response.Replace("$id","id"));编辑为@BrianRogers建议这个答案为我解决了$id/$ref问题:尽管在DefaultContractResolver中将PreserveReferencesHandling设置为“None”,Json.Net还是将$id添加到EF对象中/在IContractResolver的实现中,添加这个;publicoverrideJsonContractResolveContract(Typetype){varcontract=base.ResolveContract(type);contract.IsReference=false;退货合同;编辑:这将删除$id。以上就是C#学习教程:JsonConvert.DeserializeObject(string)为$id属性返回null值,分享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——本文来自网络合集,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处:
