RobVious
RobVious

Reputation: 12915

List<Object> serialization not working with multiple objects

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?

Upvotes: 1

Views: 99

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038930

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.

Upvotes: 1

Related Questions