背景
クライアント/サーバー構成のアプリケーションで、サーバー側にWebサービスで公開するエンティティクラスがあるとします。
複数のエンティティクラス間に、親子関係(Listで保持される関係)があった場合、双方向の参照を持たせると、WebサービスがエンティティクラスをXMLにシリアライズする際に、循環参照エラーが発生します。
public partial class Country
{
public List<Person> People { get; set; }
}
public partial class Person
{
public Country BelongingCountry { get; set; }
}
WebService.cs
[WebService(Namespace = "http://tempuri.org/")]
public class CountryService : System.Web.Services.WebService
{
[WebMethod]
public Country GetCountry(int id)
{
return Country.Get(id);
}
}
解決法
上記の状態でWebメソッドをクライアントからコールした場合、ContryとPersonの間に循環参照が発生し、例外が発生します。
これを回避するためには、PersonクラスのBelongingCountryプロパティのsetをprivate化します。
private化
get/setのいずれかがnon publicの場合、Webサービス経由でプロパティが公開されなくなります。
public partial class Person
{
public Country BelongingCountry { get; private set; }
}
XmlIgnore
public setが必要な場合は、PersonクラスのBelongingCountryプロパティに[XmlIgnore]属性を付けます。
public partial class Person
{
[XmlIgnore]
public Country BelongingCountry { get; set; }
}
これによって循環参照が回避され、Webサービス経由でエンティティが取得できるようになります。