1

I have the following classes

[DataContract]
public class Video
{
    [Key]
    [DataMember(IsRequired = false)]
    public int VideoId { get; set; }

    [DataMember(IsRequired = false)]
    public int UserId { get; set; }

    [Required]
    [DataMember ]
    public string Title { get; set; }

    [Required]
    [DataMember]
    public virtual IList<Tag> Tags { get; set; }

}

[DataContract]
public class Tag
{
    [Key]
    [Required]
    [DataMember(IsRequired = false)]
    public int? TagId { get; set; }

    [DataMember(IsRequired = true)]
    [Required]
    public string Name { get; set; }

    [IgnoreDataMember]
    public virtual IList<Video> Videos { get; set; }

}

In my WebAPI controller, I call this:

            var videos = _service.GetVideos();
            return Request.CreateResponse(HttpStatusCode.OK, videos);

Which calls this:

    public IList<Video> GetVideos()
    {
        using (var db = CreateContext())
        {
            return db.Videos.Include("Tags").ToList();
        }
    }

Yet over the wire, this is what I get:

 [{
    "$id": "8",
    "tags": [
        {
            // CORRECT SERIALIZATION
            "$id": "9",  
            "tagId": 1,
            "name": "Example",
            "count": 5
        }
    ],
    "videoId": 18,
    "userId": 3,
    "title": "Test Video",
    "thumbnail": "http://i.imgur.com/gV3J2Uf.png",
    "source": "test source"
},
 {
    "$id": "19",
    "tags": [
        {
            // WTF?
            "$ref": "9"
        }
    ],
    "videoId": 28,
    "userId": 6,
    "title": "Test Video",
    "thumbnail": "http://i.imgur.com/gV3J2Uf.png",
    "source": "test source"
},
{
    "$id": "20",
    "tags": [
        {
            // CORRECT AGAIN
            "$id": "21",
            "tagId": 10,
            "name": "funny",
            "count": 2
        }
    ],
    "videoId": 29,
    "userId": 6,
    "title": "TEST VID",
    "thumbnail": "https://i.imgur.com/SWOQSOf.jpg",
    "source": "test source"
},
{
    "$id": "22",
    "tags": [
        {
            // INCORRECT
            "$ref": "9"
        },
        {
            "$ref": "21"
        }
    ],
    "videoId": 30,
    "userId": 6,
    "title": "TEST VID",
    "thumbnail": "https://i.imgur.com/R7lVobX.jpg",
    "source": "test source"
}

For some reason - tags is sometimes serializing correctly, and sometimes not. Any idea what I'm doing wrong?


You have circular references in your object graph. They cannot be JSON serialized properly, the serializer detects this condition and automatically makes references ($ref). when you are loading the object graph using EF there are circular references between those objects in memory which cannot be represented correctly in JSON.

I would recommend you breaking the circular references graph by using a view model and then sending the view model over the wire instead of directly returning your autogenerated EF models.

4

1 回答 1

1

您的对象图中有循环引用。它们无法正确地被 JSON 序列化,序列化程序会检测到这种情况并自动进行引用 ( $ref)。当您使用 EF 加载对象图时,内存中的这些对象之间存在循环引用,无法在 JSON 中正确表示。

我建议您使用视图模型破坏循环引用图,然后通过网络发送视图模型,而不是直接返回自动生成的 EF 模型。

于 2013-08-23T16:00:44.710 回答