循环引用$对象图的对$ pventing系列化 [英] Circular references preventing serialization of object graph
问题描述
我有涉及杂草及其家庭提供简单的数据模型。
WeedFamily< -1 --- * - >杂草
(WeedFamily和杂草有一到一对多的关系)
我试图完成我的第一个ApiController,这样我可以轻松地检索我的数据作为JSON用于AngularJS应用。当我在应用程序访问 / WeedAPI /
URL,我得到以下错误。我是pretty确定问题是,我有之间循环引用杂草
和 WeedFamily
。
我应该如何改变我的数据模型,使同时保持双向品质JSON序列化将工作杂草
- WeedFamily
关系?
(即我希望仍然能够建立前pressions这样的:
WeedData.GetFamilies()[芥末。Weeds.Count
和
WeedData.GetWeeds()[3] .Family.Weeds
)
错误:
<错误>
<消息方式>发生错误< /信息>
< ExceptionMessage>
在'ObjectContent`1类型没有序列化响应正文内容类型application / xml进行;字符集= UTF-8。
< / ExceptionMessage>
< ExceptionType> System.InvalidOperationException< / ExceptionType>
<堆栈跟踪/>
<&的InnerException GT;
<消息方式>发生错误< /信息>
< ExceptionMessage>
类型对象图WeedCards.Models.WeedFamily'包含周期,如果参考禁止追踪无法被序列化。
< / ExceptionMessage>
< ExceptionType>
System.Runtime.Serialization.SerializationException
< / ExceptionType>
<&栈跟踪GT;
在System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleReference(XmlWriterDelegator的XmlWriter,obj对象,布尔canContainCyclicReference)在WriteWeedToXml(XmlWriterDelegator,对象,XmlObjectSerializerWriteContext,ClassDataContract)在System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator的XmlWriter,obj对象,XmlObjectSerializerWriteContext背景)在System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract,XmlWriterDelegator的XmlWriter,obj对象,的RuntimeTypeHandle declaredTypeHandle)在System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract,XmlWriterDelegator的XmlWriter,obj对象,的RuntimeTypeHandle declaredTypeHandle)的系统。 Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator的XmlWriter,obj对象,布尔isDecl ...等
< /堆栈跟踪>
< /&的InnerException GT;
< /错误>
我的数据:
公共类WeedData
{
公共静态字典<字符串,WeedFamily> GetFamilies(){
返回新字典<字符串,WeedFamily>
{
{芥末,新WeedFamily(芥末,十字花科)}
,{藜,新WeedFamily(藜,苋)}
{向日葵,新WeedFamily(向日葵,菊科)}
};
} 公共静态列表<杂草> GetWeeds(){
VAR家庭= GetFamilies();
返回新的List<杂草>
{
新的杂草(毛Bittercress,碎米荠,家庭[芥末])
,新的杂草(小Bittercress,碎米oligosperma家庭[芥末])
,新的杂草(荠菜,荠菜,家庭[芥末])
,新的杂草(野芥菜,野芥/田芥,家庭[芥末])
,新的杂草(野萝卜,野萝卜,家庭[芥末])
,新的杂草(萝卜,萝卜,家庭[芥末])
,新的杂草(反枝苋,反枝苋,家庭[猪草])
,新的杂草(野莴苣,野莴苣,家庭[向日葵])
,新的杂草(刺苦菜,花叶滇苦菜,家庭[向日葵])
,新的杂草(「股东周年苦菜,荼,家庭[向日葵]) };
}
}
我的模型类:
[Serializable接口]
公共类杂草
{
公共字符串通用名称;
公共字符串LatinName;
公开名单< WeedPhoto>相片;
公共WeedFamily家庭; 公共杂草(字符串COMMONNAME,串latinName)
{
通用名称=通用名称;
LatinName = latinName;
} 公共杂草(字符串COMMONNAME,串latinName,WeedFamily家族)
{
通用名称=通用名称;
LatinName = latinName;
家庭=家庭;
Family.Weeds.Add(本);
} 覆盖公共字符串的ToString()
{
返回通用名称+(+ LatinName +);
}
}
和
[Serializable接口]
公共类WeedFamily
{
公共字符串通用名称;
公共字符串LatinName;
公开名单<杂草>杂草; 公共WeedFamily(字符串COMMONNAME,串latinName)
{
通用名称=通用名称;
LatinName = latinName;
杂草=新的List<杂草>();
}
}
最后,ApiController:
公共类WeedAPIController:ApiController
{
//
// GET:/ WeedAPI / 公共IEnumerable的<杂草> GetAllWeeds()
{
返回WeedData.GetWeeds();
}}
添加 [DataContract(IsReference = TRUE)]
来有循环引用的对象。
[Serializable接口]
[DataContract(IsReference =真)]
公共类WeedFamily[Serializable接口]
[DataContract(IsReference =真)]
公共类杂草
请参阅http://msdn.microsoft.com/en-us/library/vstudio/hh241056(v=vs.100).aspx
I've got a simple data model involving Weeds and Weed Families.
WeedFamily <-1---*-> Weed
(WeedFamily and Weed have a one-to-many relationship)
I'm attempting to complete my first ApiController so that I can easily retrieve my data as JSON for an AngularJS application. When I access the /WeedAPI/
URL in my application, I get the following error. I'm pretty sure the problem is that I have circular references between Weed
and WeedFamily
.
How should I change my data model so that the JSON serialization will work while maintaining the bi-directional quality of the Weed
-WeedFamily
relationship?
(ie. I want to still be able to build expressions like the following:
WeedData.GetFamilies()["mustard"].Weeds.Count
and
WeedData.GetWeeds()[3].Family.Weeds
)
The error:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Object graph for type 'WeedCards.Models.WeedFamily' contains cycles and cannot be serialized if reference tracking is disabled.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleReference(XmlWriterDelegator xmlWriter, Object obj, Boolean canContainCyclicReference) at WriteWeedToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDecl...etc
</StackTrace>
</InnerException>
</Error>
My data:
public class WeedData
{
public static Dictionary<string,WeedFamily> GetFamilies(){
return new Dictionary<string,WeedFamily>
{
{"mustard",new WeedFamily("Mustard","Brassicaceae")}
,{"pigweed",new WeedFamily("Pigweed","Amaranthus")}
,{"sunflower",new WeedFamily("Sunflower","Asteraceae")}
};
}
public static List<Weed> GetWeeds(){
var Families = GetFamilies();
return new List<Weed>
{
new Weed("Hairy Bittercress","Cardamine hirsuta",Families["mustard"])
,new Weed("Little Bittercress","Cardamine oligosperma",Families["mustard"])
,new Weed("Shepherd's-Purse","Capsella bursa-pastoris",Families["mustard"])
,new Weed("Wild Mustard","Sinapis arvensis / Brassica kaber",Families["mustard"])
,new Weed("Wild Radish","Raphanus raphanistrum",Families["mustard"])
,new Weed("Radish","Raphanus sativus",Families["mustard"])
,new Weed("Redroot Pigweed","Amaranthus retroflexus",Families["pigweed"])
,new Weed("Prickly Lettuce","Lactuca serriola",Families["sunflower"])
,new Weed("Spiny Sowthistle","Sonchus asper",Families["sunflower"])
,new Weed("Annual Sowthistle","Sonchus oleraceus",Families["sunflower"])
};
}
}
My model classes:
[Serializable]
public class Weed
{
public string CommonName;
public string LatinName;
public List<WeedPhoto> Photos;
public WeedFamily Family;
public Weed(string commonName, string latinName)
{
CommonName = commonName;
LatinName = latinName;
}
public Weed(string commonName, string latinName, WeedFamily family)
{
CommonName = commonName;
LatinName = latinName;
Family = family;
Family.Weeds.Add(this);
}
override public string ToString()
{
return CommonName + " (" + LatinName + ")";
}
}
and
[Serializable]
public class WeedFamily
{
public string CommonName;
public string LatinName;
public List<Weed> Weeds;
public WeedFamily(string commonName, string latinName)
{
CommonName = commonName;
LatinName = latinName;
Weeds = new List<Weed>();
}
}
Finally, the ApiController:
public class WeedAPIController : ApiController
{
//
// GET: /WeedAPI/
public IEnumerable<Weed> GetAllWeeds()
{
return WeedData.GetWeeds();
}
}
Add [DataContract(IsReference = true)]
to the objects that have circular references.
[Serializable]
[DataContract(IsReference = true)]
public class WeedFamily
[Serializable]
[DataContract(IsReference = true)]
public class Weed
See http://msdn.microsoft.com/en-us/library/vstudio/hh241056(v=vs.100).aspx
这篇关于循环引用$对象图的对$ pventing系列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!