Circular Reference. I really need help ... thanks.

S

shapper

Hello,

On an ASP.NET MVC project I am getting a list of Tags which names
start with a string contained on the variable "q".

Everything works fine if no Post is related to Tags.
When there is relation I start to get a Circular Reference error.

I have been trying to solve this problem for days!
I can't find the reason for this, either in my SQL or C# code.

I am posting both codes ... just in case:

C# LINQ code:

public JsonResult Filter(string q, int limit) {

var list = (from t in database.Tags
where t.Name.StartsWith(q)
orderby t.Name
select t);
List<Tag> tags = (limit > 0 ? list.Take(limit) : list).ToList();
return this.Json(tags);

}

SQL Tables:

Code:
-- Files
create table dbo.Files
(
FileID uniqueidentifier not null
constraint PK_File primary key clustered,
CreatedAt datetime null,
Description nvarchar(2000) null,
IsPublished bit null,
Path nvarchar(800) null,
Title nvarchar(400) null,
UpdatedAt datetime null
)

-- Posts
create table dbo.Posts
(
PostID uniqueidentifier not null
constraint PK_Post primary key clustered,
Body nvarchar(max) null,
CreatedAt datetime null,
IsPublished bit null,
Title nvarchar(400) null,
UpdatedAt datetime null
)

-- Tags
create table dbo.Tags
(
TagID uniqueidentifier not null
constraint PK_Tag primary key clustered,
[Name] nvarchar(100) null
)

-- FilesTags
create table dbo.FilesTags
(
FileID uniqueidentifier not null,
TagID uniqueidentifier not null,
constraint PK_FilesTags
primary key clustered (FileID, TagID),
constraint FK_FilesTags_Files
foreign key(FileID)
references dbo.Files(FileID)
on delete cascade,
constraint FK_FilesTags_Tags
foreign key(TagID)
references dbo.Tags(TagID)
on delete cascade
)

-- PostsTags
create table dbo.PostsTags
(
PostID uniqueidentifier not null,
TagID uniqueidentifier not null,
constraint PK_PostsTags
primary key clustered (PostID, TagID),
constraint FK_PostsTags_Posts
foreign key(PostID)
references dbo.Posts(PostID)
on delete cascade,
constraint FK_PostsTags_Tags
foreign key(TagID)
references dbo.Tags(TagID)
on delete cascade
)

DATA in Tables (All other tables are empty):

Posts

PostID: 78ef0b05-ca4c-4df8-88c9-2858d24fa4e3
Body: <p>Test</p>
CreateAt: 03-09-2008 22:35:25
IsPublished: True
Title: This is the title
UpdatedDate: 03-09-2008 22:35:25

Tags

TagID: e2ec18a7-d668-477b-977b-183989df2a65
Name: Net

TagID: dbf4465a-d0f6-4145-831d-b1ce1363dd16
Name: New York

TagID: 0ea15666-155b-4237-a871-d905a2685f45
Name: Australia

PostsTags

TagID: e2ec18a7-d668-477b-977b-183989df2a65
PostID: 78ef0b05-ca4c-4df8-88c9-2858d24fa4e3

TagID: dbf4465a-d0f6-4145-831d-b1ce1363dd16
PostID: 78ef0b05-ca4c-4df8-88c9-2858d24fa4e3

My Linq code is automaticly generated by LinqToSQL in VS2008.

I don't see any problem in my code or data but I get the error:

A circular reference was detected while serializing an object of type
'MyApp.Models.Post'

I detected the error in FireFox FireBug because the AutoComplete most
of the time does not work.

Does anyone sees anything wrong?!

Thanks,
Miguel
 
P

Pavel Minaev

shapper said:
Everything works fine if no Post is related to Tags.
When there is relation I start to get a Circular Reference error.

I have been trying to solve this problem for days!
I can't find the reason for this, either in my SQL or C# code.

I am posting both codes ... just in case:

C# LINQ code:

public JsonResult Filter(string q, int limit) {

var list = (from t in database.Tags
where t.Name.StartsWith(q)
orderby t.Name
select t);
List<Tag> tags = (limit > 0 ? list.Take(limit) : list).ToList();
return this.Json(tags);

}

Without the definition for Json() method, this doesn't tell much.
 
S

shapper

Without the definition for Json() method, this doesn't tell much.

JSON is from ASP.NET MVC Preview 5...

I found the a explanation for this in: http://www.west-wind.com/Weblog/posts/147218.aspx

I was reading the article but its explanation implies changes to the
model which he also says that have a downside.

In this case I am serializing a list of Tags ... each Tag has 2
properties: TagID and Name ...

All I need is only the names of the selected Tags ... so couldn't I
just pick the Names of all Tags in the list create an object or a new
list and serialize it?

Maybe a list of String? An Array?

Maybe this would solve the problem without needing to change the
model ...

Any idea how to do this?

Thanks,

Miguel
 
S

shapper

JSON is from ASP.NET MVC Preview 5...

I found the a explanation for this in:http://www.west-wind.com/Weblog/posts/147218.aspx

I was reading the article but its explanation implies changes to the
model which he also says that have a downside.

In this case I am serializing a list of Tags ... each Tag has 2
properties: TagID and Name ...

All I need is only the names of the selected Tags ... so couldn't I
just pick the Names of all Tags in the list create an object or a new
list and serialize it?

Maybe a list of String? An Array?

Maybe this would solve the problem without needing to change the
model ...

Any idea how to do this?

Thanks,

Miguel

Just solved it:

// Define list
var list = (from t in database.Tags
where t.Name.StartsWith(q)
orderby t.Name
select t.Name);

// Define tags
string[] tags = (limit > 0 ? list.Take(limit) : list).ToArray();

// Return tags
return this.Json(tags);

Thanks,
Miguel
 
K

kalyan r

I ran into the same problem and THE ONE OF SOLUTION IS to

Use [ScriptIgnore] atribute .. it will solve the problem.

add system.web.extensions reference and add namespace:

Using System.Web.Script.Serialization.

If you still have questions..Read on..for some detailed explanation..

i have a User class with..

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using Iesi.Collections.Generic;

using System.Runtime.Serialization;

namespace RAPortal.Core.Entities

{

public class User

{

private int _userId;

private string _firstName;

private string _lastName;

private IList<Application> _applications;

private IList<Group> _groups;

private IList<ApplicationRequest> _applicationRequests;

Properties..

public virtual int UserId

{

get

{

return _userId;

}

set

{

_userId = value;

}

}

public virtual string Title

{

get

{

return _title;

}

set

{

_title = !String.IsNullOrEmpty(value) ? value.ToUpper().Trim() : null;

}

}

public virtual IList<Group> Groups

{

get

{

return _groups;

}

set

{

_groups = value;

}

}

public virtual IList<UserPrivilege> UserPrivileges

{

get

{

return _userPrivileges;

}

set

{

_userPrivileges = value;

}

}

public virtual IList<UserRole> UserRoles

{

get

{

return _userRoles;

}

set

{

_userRoles = value;

}

}

....so on...

and I have Groups class..

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Script.Serialization;

using System.Runtime.Serialization;

namespace RAPortal.Core.Entities

{

public class Group

{

private int _groupId;

private string _name;

private IList<User> _users;

public virtual int GroupId

{

get

{

return _groupId;

}

set

{

_groupId = value;

}

}

public virtual string Name

{

get

{

return _name;

}

set

{

_name = !String.IsNullOrEmpty(value) ? value.ToUpper().Trim() : null;

}

}

[ScriptIgnore]

public virtual IList<User> Users

{

get

{

return _users;

}

set

{

_users = value;

}

}

}

}

Since User is referenced in the groups.. the json think that it is Circular reference and It will throw an exception..so the fix is to add [ScriptIgnore] on top of the User. And add the reference and namespace to this class like it..

It solved my problem .. I am sure there are better ways out there !!! Cheers...

And remember you should add [scriptIgnore] only in the groups class and not in the Users class..



Posted as a reply to:

Re: Circular Reference. I really need help ... thanks.


Without the definition for Json() method, this doesn't tell much.

EggHeadCafe - Software Developer Portal of Choice
WCF Workflow Services Using External Data Exchange
http://www.eggheadcafe.com/tutorial...a-6dafb17b6d74/wcf-workflow-services-usi.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top