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

遗留属性名json反序列化share

时间:2023-04-10 22:58:27 C#

json遗留属性名反序列化下面是一个需要序列化和反序列化的示例对象。我给定了一个属性属性,其中包含过去可能已序列化的名称列表。[DataContract]classTestObject{[LegacyDataMemberNames("alpha","omega")][DataMember(Name="a")]publicintA{get;放;我希望json序列化始终使用名称“a”,但能够从任何遗留名称反序列化为属性,包括“alpha”和“omega”以及当前名称“a”。这可以通过扩展由预先存在的解析器创建的自定义IContractResolver来完成,例如DefaultContractResolver::Attribute{publicLegacyDataMemberNamesAttribute():this(newstring[0]){}publicLegacyDataMemberNamesAttribute()[]names){this.Names=names;}公共字符串[]名称{得到;放;}}publicclassLegacyPropertyResolver:DefaultContractResolver{//从7.0.1开始,出于性能原因,Json.NET建议对“无状态”契约解析器使用静态实例。//http://www.newtonsoft.com/json/help/html/ContractResolver.htm//http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm//“在您的应用程序中使用无参数构造函数和缓存契约解析器实例以获得最佳性能。”静态LegacyPropertyResolver实例;静态LegacyPropertyResolver(){实例=newLegacyPropertyResolver();}publicstaticLegacyPropertyResolverInstance{get{返回实例;}}protectedLegacyPropertyResolver():base(){}protectedoverrideIListCreateProperties(Typetype,MemberSerializationmemberSerialization){varproperties=base.CreateProperties(type,memberSerialization);对于(inti=0,n=properties.Count;i().SelectMany(a=>a.Names)){if(properties.Any(p=>p.PropertyName==name)){Debug.WriteLine(“重复的LegacyDataMemberNamesAttribute:”+名称);继续;}varnewProperty=(JsonProperty)clone.Invoke(property,newobject[0]);newProperty.Readable=false;newProperty.PropertyName=名称;properties.Add(newProperty);}}返回属性;请注意,此实现不要求类具有显式数据协定属性注释。您可以根据需要添加该限制。然后将它与下面的JsonSerializerSettings:varsettings=newJsonSerializerSettings{ContractResolver=LegacyPropertyResolver.Instance};例如:[DataContract]classTestObject{[LegacyDataMemberNames("alpha","omega")][DataMember(Name="a")]publicintA{get;放;}}publicstaticclassJsonExtensions{publicstaticvoidRenameProperty(thisJObjectobj,stringoldName,stringnewName){if(obj==null)thrownewNullReferenceException();varproperty=obj.Property(oldName);if(property!=null){property.Replace(newJProperty(newName,property.Value));}}}publicclassTestClass{publicstaticvoidTest(){try{TestInner();}catch(Exceptionex){Debug.Assert(false,ex.ToString());//没有断言抛出;}}publicstaticvoidTestInner(){vartest=newTestObject{A=42};varsettings=newJsonSerializerSettings{ContractResolver=LegacyPropertyResolver.Instance};varjson=JObject.FromObject(测试,JsonSerializer.CreateDefault(设置));if(json.SelectToken("alpha")!=null||json.SelectToken("omega")!=null)thrownewInvalidOperationException("序列化失败");测试(测试,json);json.RenameProperty("a","alpha");测试(测试,json);json.RenameProperty("alpha","omega");测试(测试,json);}privatestaticvoidTest(TestObjecttest,JObjectjson){vartest1=json.ToObject(JsonSerializer.CreateDefault(newJsonSerializerSettings{ContractResolver=LegacyPropertyResolver.Instance}));if(test1.A!=test.A)thrownewInvalidOperationException("反序列化失败");Console.WriteLine("反序列化成功:"+json.ToString(Formatting.None));Debug.WriteLine("反序列化成功:"+json.ToString(Formatting.None));我拿了你的代码并将其修改为我自己的样式,如下所示:LegacyDataMemberNamesAttribute:属性{publicreadonlystring[]LegacyNames;publicLegacyDataMemberNamesAttribute(paramsstring[]legacyNames){LegacyNames=legacyNames;}}publicclassLegacyPropertyResolver:DefaultContractResolver{//从7.0.1开始,出于性能原因,Json.NET建议对“无状态”契约解析器使用静态实例。//http://www.newtonsoft.com/json/help/html/ContractResolver.htm//http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm//“使用无参数构造函数和在您的应用程序中缓存合同解析器的实例以获得最佳性能。”publicstaticreadonlyLegacyPropertyResolverInstance=newLegacyPropertyResolver();受保护的LegacyPropertyResolver():base(){}protectedoverrideIListCreateProperties(Typetype,MemberSerializationmemberSerialization){varproperties=base.CreateProperties(type,memberSerialization);foreach(properties.ToAr中的var属性ray()){如果(!property.Writable)继续;foreach(varlegacyNameinGetLegacyNames(property)){properties.Add(CloneWithLegacyName(property,legacyName));}}返回属性;}staticIEnumerableGetLegacyNames(JsonPropertyproperty){returnproperty.AttributeProvider.GetAttributes(typeof(LegacyDataMemberNamesAttribute),true).Cast().SelectMany(a=>a.LegacyNames).Distinct();}staticreadonlyobject[]_emptyObjectArray=newobject[0];staticreadonlyMethodInfo_propertyClone=typeof(JsonProperty).GetMethod("MemberwiseClone",BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);staticJsonPropertyCloneWithLegacyName(JsonPropertyproperty,stringlegacyName){varlegacyProperty=(JsonProperty)_propertyClone.Invoke(property,_emptyObjectArray);legacyProperty.Readable=false;legacyProperty.PropertyName=legacyName;返回legacyProperty;使用Json.NET的一个非常简单的解决方案是只提供带有setter的遗留属性类TestObject{publicintA{get;放;}publicintalpha{set=>A=value;}publicintomega{set=>A=value;您可能不希望这些公开,在这种情况下您可以标记为私有并添加JsonProperty属性。以上就是C#学习教程:从遗留属性名反序列化json的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——classTestObject{publicintA{get;放;}[JsonProperty]privateintalpha{set=>A=value;}[JsonProperty]privateintomega{set=>A=value;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理会员删除。如需转载请注明出处: