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

JSON.net(de)序列化无类型属性分享

时间:2023-04-11 01:17:47 C#

JSON.net(de)序列化无类型属性假设我有这样一个类:publicclassExample{publicintTypedProperty{get;放;}公共对象UntypedProperty{得到;放;}}假设有人出现并写道:varexample=newExample{TypedProperty=5,UntypedProperty=Guid.NewGuid()}如果我用JsonConvert.SerializeObject(example)序列化它,我得到{"TypedProperty":5,"UntypedProperty":"24bd733f-2ade-4374-9db6-3c9f3d97b12c"}理想情况下我想得到这样的东西:{"TypedProperty":5,"UntypedProperty":{"$type":"System.Guid,mscorlib","$value":"24bd733f-2ade-4374-9db6-3c9f3d97b12c"}}但TypeNameHandling在这种情况下不起作用。我如何(反)序列化未类型化的属性?如果一个类是使用TypeNameHandling.All或TypeNameHandling.Auto序列化的,那么当一个UntypedProperty属性被序列化为JSON容器(对象或数组)时,Json.NET应该通过将类型信息存储在JSON文件中来正确地序列化和反序列化把它在“$type”属性中。但是,如果将UntypedProperty序列化为JSON原语(字符串、数字或布尔值),这将不起作用,因为正如您所指出的,JSON原语没有机会包含“$type”属性。当使用类型对象的属性序列化类型时,解决方案是序列化一个包装类,该包装类可以根据此答案的行封装类型信息的原始值。这是一个自定义的JSON转换器,它输入了这样一个封装器:JsonSerializer.Converters");}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){if(reader.TokenType==JsonToken.Null)returnnull;varvalue=serializer.Deserialize(reader,objectType);if(valueisTypeWrapper){return((TypeWrapper)value).ObjectValue;}返回值;}publicoverridevoidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){if(serializer.TypeNameHandling==TypeNameHandling.None){Console.WriteLine("ObjectItemConverterusedwhenserializer.TypeNameHandling==TypeNameHandling.None");serializer.Serialize(writer,value);}//处理几个简单的原始情况,其中一个类型不需要包装器elseif(valueisstring){writer.WriteValue((string)value);}elseif(valueisbool){writer.WriteValue((bool)value);}else{varcontract=serializer.ContractResolver.ResolveContract(value.GetType());if(contractisJsonPrimitiveContract){varwrapper=TypeWrapper.CreateWrapper(value);serializer.Serialize(writer,wrapper,typeof(object));}else{serializer.Serialize(writer,value);}}}}抽象类TypeWrapper{protectedTypeWrapper(){}[JsonIgnore]publicabstractobjectObjectValue{get;}publicstaticTypeWrapperCreateWrapper(Tvalue){if(value==null)returnnewTypeWrapper();vartype=value.GetType();if(type==typeof(T))returnnewTypeWrapper(value);//返回子类的实际类型return(TypeWrapper)Activator.CreateInstance(typeof(TypeWrapper).MakeGenericType(type),value);}}sealedclassTypeWrapper:TypeWrapper{publicTypeWrapper():base(){}publicTypeWrapper(Tvalue):base(){this.Value=value;}publicoverrideobjectObjectValue{get{返回值;}}publicT值{get;放;然后使用[JsonConverter(typeof(UntypedToTypedValueConverter))]将其应用于您的类型:publicclassExample{publicintTypedProperty{get;放;}[JsonConverter(typeof(UntypedToTypedValueConverter))]publicobjectUntypedProperty{get;放;如果您不能以任何方式修改Example类以添加此属性(您的注释类不是我的更改建议)您可以使用自定义合同解析器注入转换器:publicclassUntypedToTypedPropertyContractResolver:DefaultContractResolver{readonlyUntypedToTypedValueConverter转换器=newUntypedToTypedValueConverter();//从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//“使用无参数构造函数和缓存合约实例应用程序中的解析器以获得最佳性能。”//另请参阅https://stackoverflow.com/questions/33557737/does-json-net-cache-types-serialization-informationstaticUntypedToTypedPropertyContractResolver实例;//显式静态构造函数告诉C#编译器不要将类型标记为before;foreach(varpropertyincontract.Properties.Concat(contract.CreatorParameters)){if(property.PropertyType==typeof(object)&&property.Converter==null){property.Converter=property.MemberConverter=converter;}}returncontract;}}并使用如下:varsettings=newJsonSerializerSettings{TypeNameHandling=TypeNameHandling.Auto,ContractResolver=UntypedToTypedPropertyContractResolver.Instance,};varjson=JsonConvert.SerializeObject(示例,Formatting.Indented,设置);varexample2=JsonConvert.DeserializeObject(json,设置);在这两种情况下,创建JSON如下所示:{"TypedProperty":5,"UntypedProperty":{"$type":"Question38777588.TypeWrapper`1[[System.Guid,mscorlib]],Tile","Value":"e2983c59-5ec4-41cc-b3fe-34d9d0a97f22"}}找到SerializeWithJsonConverters.htm和ReadingWritingJSON调用:JsonConvert.SerializeObject(例如,newObjectConverter());以上就是C#学习教程:JSON.net(de)序列化untypedproperties分享的所有内容,如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——classObjectConverter:JsonConverter{publicoverrideboolCanConvert(TypeobjectType){returnobjectType==typeof(例子);}publicoverrideobjectReadJson(JsonReaderreader,TypeobjectType,objectexistingValue,JsonSerializerserializer){newNotImplementedException();}publicoverridevoidWriteJson(JsonWriterwriter,objectvalue,JsonSerializerserializer){Examplee=(Example)value;writer.WriteStartObject();writer.WritePropertyName("TypedProperty");writer.WriteValue(e.TypedProperty);writer.WritePropertyName("UntypedProperty");writer.WriteStartObject();writer.WritePropertyName("$type");writer.WriteValue(e.UntypedProperty.GetType().FullName);writer.WritePropertyName("$value");writer.WriteValue(e.UntypedProperty.ToString());writer.WriteEndObject();writer.WriteEndObject();}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: