ServiceStack.Text序列化循环引用我需要序列化一个对象图是这样的:publicclassA{publicBLink1{get;set;}}publicclassB{publicALink2{get;set;}}这样json只获取两个实例,但再次正确反序列化。例如,使用元ID或类似的东西。我知道Json.NET中有一种方法,如下所述:http://note.harajuku-tech.org/serializing-circular-references-with-jsonnetwithmetaids。ServiceStack.TextJsonSerializer中是否有类似的功能?否则,是否可以将Json.NET与ServiceStack一起使用以及如何使用?编辑:为了清楚起见,我要求的是实例引用,而不仅仅是相同的类型。例如:[{"$id":"1","BroId":0,"Name":"John","Bros":[{"$id":"2","BroId":0,"Name":"Jared","Bros":[{"$ref":"1"}]}]},{"$ref":"2"}]只有2个对象是“真正”序列化的,其余部分使用$ref属性字段重用。想象一个带有子集合的对象模型。这些孩子有对其父对象的反向引用。EG客户/订单。一个客户有多个订单,每个订单都有一个对其客户的引用。现在想想如果序列化一个客户端会发生什么。Customer->Order->Customer->Order->...你会得到类似这个网站名称的东西。;)我真的很喜欢ServiceStack的清晰度,不需要KnownTypeAttribute等。我想保持它干净,而不是在我的业务逻辑pocos中实现自定义加载器/对象初始化器。我用另一种方式解决了这个问题。这确实有效,但在使用具有多个循环引用的更复杂的数据结构时可能会出现问题。但目前没有必要。我尝试向ServiceStack.Text添加循环引用功能,但发现没有必要从它开始。也许mythz可以给我一个提示?功能应该非常简单。我需要此功能来序列化我的数据模型以完全支持NHibernate的合并功能。我遵循了mythz的建议并忽略了导致循环引用的IgnoreDataMemberAttribute属性。但这也需要在反序列化后重建它们才能使合并正常工作。->这是解决方案,现在按照我的方式进行:我开始使用一个简单的原型(数据模型Customer1->nOrders1->nOrders)对此进行测试。每个类都派生自实体类。公共类客户:实体{公共虚拟字符串名称{get;放;}publicvirtualstringCity{get;放;}publicvirtualIListOrders{get;放;}}publicclassOrder:Entity{publicvirtualDateTimeOrderDate{get;放;}publicvirtualIListOrderDetails{get;放;}[IgnoreDataMember]publicvirtualCustomerCustomer{get;放;}}publicclassOrderDetail:Entity{publicvirtualstringProductName{get;放;}publicvirtualintAmount{get;放;}[IgnoreDataMember]publicvirtualOrderOrder{get;放;正如您所看到的,Order和OrderDetail具有对其父对象的反向引用,这会在序列化时导致循环引用。这可以通过使用IgnoreDataMemberAttribute忽略反向引用来完成。我当前的假设是Customer列表属性Orders中Order的每个子实例都有对此Customer实例的反向引用。所以这就是我重建圆树的方式:publicstaticclassSerializationExtensions{publicstaticvoidUpdateChildReferences(thisobjectinput){varhashDictionary=newDictionary();hashDictionary.Add(input.GetHashCode(),输入);varprops=input.GetType().GetProperties();foreach(varpropertyInfoinprops){if(propertyInfo.PropertyType.GetInterfaces().Any(t=>t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(IEnumerable))){varinstanceTypesInList=propertyInfo.PropertyType.GetGenericArguments();如果(instanceTypesInList.Length!=1)继续;如果(instanceTypesInList[0].IsSubclassOf(typeof(Entity))){varlist=(IList)propertyInfo.GetValue(input,null);foreach(列表中的对象t){UpdateReferenceToParent(输入,t);更新子引用(t);}}}}}privatestaticvoidUpdateReferenceToParent(objectparent,objectitem){varprops=item.GetType().GetProperties();varresult=props.FirstOrDefault(x=>x.PropertyType==parent.GetType());if(result!=null)result.SetValue(item,parent,null);这段代码现在不适用于1->1实体引用(不需要),但我认为它可以很容易地扩展,现在允许我在客户端有一个POCO类模型,孩子添加/更新/删除对象并将整个树发送回服务器。Nhibernate足够聪明,可以确定哪个实体是新的/更新的/删除的。它还只更新已更改的实体,并且仅更新已更改的属性!如果删除订单,它还会删除所有OrderDetails。这是流畅的nhibernate映射的完整特性:publicclassCustomerMap:ClassMap{publicCustomerMap(){Schema("YOURSCHEMA");表(“客户”);Id(x=>x.Id,"ID").GeneratedBy.Assigned();Map(x=>x.Name,"NAM");Map(x=>x.City,"CITY");HasMany(x=>x.Orders).KeyColumn("CUSTOMER_ID").Not.LazyLoad().Inverse().Cascade.AllDeleteOrphan();动态更新();}}publicclassOrderMap:ClassMap{publicOrderMap(){Schema("YOURSCHEMA");表(“CUSTOMER_ORDER”);Id(x=>x.Id,"ID").GeneratedBy.Assigned();Map(x=>x.OrderDate,"ORDER_DATE");HasMany(x=>x.OrderDetails).KeyColumn("ORDER_ID").Not.LazyLoad().Inverse().Cascade.AllDeleteOrphan();引用(x=>x.Customer,“CUSTOMER_ID”);动态更新();}}publicclassOrderDetailMap:ClassMap{publicOrderDetailMap(){Schema("YOURSCHEMA");表(“ORDER_DETAIL”);Id(x=>x.Id,"ID").GeneratedBy.Assigned();Map(x=>x.ProductName,"PRODUCT_NAME");Map(x=>x.Amount,"AMOUNT");引用(x=>x.Order,“ORDER_ID");DynamicUpdate();}}DynamicUpdate()用于让nhibernate只更新已更改的属性你现在只需要使用ISession.Merge(customer)函数来正确保存所有内容。ServiceStack默认支持循环引用。为什么不在发布中尝试自己事先验证是否存在实际问题?这比创建一个新问题并要求其他人做同样的事情要省力。按照你的例子:publicclassA{publicstringName{get;放;}publicBLink1{得到;放;}}publicclassB{publicstringName{get;放;}publicALink2{得到;放;}}vardto=newA{Name="A1",Link1=newB{Name="B1",Link2=newA{Name="A2"}}};dto.ToJson().Print();将打印JSONString:{"Name":"A1","Link1":{"Name":"B1","Link2":{"Name":"A2"}}}同时将其序列化为JSON并再次反序列化喜欢:varfromJson=dto.ToJson().FromJson();fromJson.PrintDump();将转储内容:{Name:A1,Link1:{Name:B1,Link2:{Name:A2}}}如果有人需要能够使用循环序列化对象图,JSON.NET确实支持它:以上是C#学习教程全部内容:ServiceStack.Text序列化循环引用,如果对大家有用,需要深入了解C#学习教程,希望大家多多关注——newJsonSerializer{PreserveReferencesHandling=PreserveReferencesHandling.Objects};本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
