Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6639407
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T23:33:02+00:00 2026-05-25T23:33:02+00:00

Like several other people, I’m having problems serializing Entity Framework objects, so that I

  • 0

Like several other people, I’m having problems serializing Entity Framework objects, so that I can send the data over AJAX in a JSON format.

I’ve got the following server-side method, which I’m attempting to call using AJAX through jQuery

[WebMethod]
public static IEnumerable<Message> GetAllMessages(int officerId)
{

        SIBSv2Entities db = new SIBSv2Entities();

        return  (from m in db.MessageRecipients
                        where m.OfficerId == officerId
                        select m.Message).AsEnumerable<Message>();
}

Calling this via AJAX results in this error:

A circular reference was detected while serializing an object of type \u0027System.Data.Metadata.Edm.AssociationType

Which is because of the way the Entity Framework creates circular references to keep all the objects related and accessible server side.

I came across the following code from (http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/) which claims to get around this problem by capping the maximum depth for references. I’ve added the code below, because I had to tweak it slightly to get it work (All angled brackets are missing from the code on the website)

using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System;


public class EFObjectConverter : JavaScriptConverter
{
  private int _currentDepth = 1;
  private readonly int _maxDepth = 2;

  private readonly List<int> _processedObjects = new List<int>();

  private readonly Type[] _builtInTypes = new[]{
    typeof(bool),
    typeof(byte),
    typeof(sbyte),
    typeof(char),
    typeof(decimal),
    typeof(double),
    typeof(float),
    typeof(int),
    typeof(uint),
    typeof(long),
    typeof(ulong),
    typeof(short),
    typeof(ushort),
    typeof(string),
    typeof(DateTime),
    typeof(Guid)
  };

  public EFObjectConverter( int maxDepth = 2,
                            EFObjectConverter parent = null)
  {
    _maxDepth = maxDepth;
    if (parent != null)
    {
      _currentDepth += parent._currentDepth;
    }
  }

  public override object Deserialize( IDictionary<string,object> dictionary, Type type, JavaScriptSerializer serializer)
  {
    return null;
  }     

  public override IDictionary<string,object> Serialize(object obj, JavaScriptSerializer serializer)
  {
    _processedObjects.Add(obj.GetHashCode());
    Type type = obj.GetType();
    var properties = from p in type.GetProperties()
                      where p.CanWrite &&
                            p.CanWrite &&
                            _builtInTypes.Contains(p.PropertyType)
                      select p;
    var result = properties.ToDictionary(
                  property => property.Name,
                  property => (Object)(property.GetValue(obj, null)
                              == null
                              ? ""
                              :  property.GetValue(obj, null).ToString().Trim())
                  );
    if (_maxDepth >= _currentDepth)
    {
      var complexProperties = from p in type.GetProperties()
                                where p.CanWrite &&
                                      p.CanRead &&
                                      !_builtInTypes.Contains(p.PropertyType) &&
                                      !_processedObjects.Contains(p.GetValue(obj, null)
                                        == null
                                        ? 0
                                        : p.GetValue(obj, null).GetHashCode())
                              select p;

      foreach (var property in complexProperties)
      {
        var js = new JavaScriptSerializer();

          js.RegisterConverters(new List<JavaScriptConverter> { new EFObjectConverter(_maxDepth - _currentDepth, this) });

        result.Add(property.Name, js.Serialize(property.GetValue(obj, null)));
      }
    }

    return result;
  }

  public override IEnumerable<System.Type> SupportedTypes
  {
    get
    {
      return GetType().Assembly.GetTypes();
    }
  }

}

However even when using that code, in the following way:

    var js = new System.Web.Script.Serialization.JavaScriptSerializer();
    js.RegisterConverters(new List<System.Web.Script.Serialization.JavaScriptConverter> { new EFObjectConverter(2) });
    return js.Serialize(messages);

I’m still seeing the A circular reference was detected... exception being thrown!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T23:33:03+00:00Added an answer on May 25, 2026 at 11:33 pm

    I solved these issues with the following classes:

    public class EFJavaScriptSerializer : JavaScriptSerializer
      {
        public EFJavaScriptSerializer()
        {
          RegisterConverters(new List<JavaScriptConverter>{new EFJavaScriptConverter()});
        }
      }
    

    and

    public class EFJavaScriptConverter : JavaScriptConverter
      {
        private int _currentDepth = 1;
        private readonly int _maxDepth = 1;
    
        private readonly List<object> _processedObjects = new List<object>();
    
        private readonly Type[] _builtInTypes = new[]
        {
          typeof(int?),
          typeof(double?),
          typeof(bool?),
          typeof(bool),
          typeof(byte),
          typeof(sbyte),
          typeof(char),
          typeof(decimal),
          typeof(double),
          typeof(float),
          typeof(int),
          typeof(uint),
          typeof(long),
          typeof(ulong),
          typeof(short),
          typeof(ushort),
          typeof(string),
          typeof(DateTime),
          typeof(DateTime?),
          typeof(Guid)
      };
        public EFJavaScriptConverter() : this(1, null) { }
    
        public EFJavaScriptConverter(int maxDepth = 1, EFJavaScriptConverter parent = null)
        {
          _maxDepth = maxDepth;
          if (parent != null)
          {
            _currentDepth += parent._currentDepth;
          }
        }
    
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
          return null;
        }
    
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
          _processedObjects.Add(obj.GetHashCode());
          var type = obj.GetType();
    
          var properties = from p in type.GetProperties()
                           where p.CanRead && p.GetIndexParameters().Count() == 0 &&
                                 _builtInTypes.Contains(p.PropertyType)
                           select p;
    
          var result = properties.ToDictionary(
                        p => p.Name,
                        p => (Object)TryGetStringValue(p, obj));
    
          if (_maxDepth >= _currentDepth)
          {
            var complexProperties = from p in type.GetProperties()
                                    where p.CanRead &&
                                          p.GetIndexParameters().Count() == 0 &&
                                          !_builtInTypes.Contains(p.PropertyType) &&
                                          p.Name != "RelationshipManager" &&
                                          !AllreadyAdded(p, obj)
                                    select p;
    
            foreach (var property in complexProperties)
            {
              var complexValue = TryGetValue(property, obj);
    
              if(complexValue != null)
              {
                var js = new EFJavaScriptConverter(_maxDepth - _currentDepth, this);
    
                result.Add(property.Name, js.Serialize(complexValue, new EFJavaScriptSerializer()));
              }
            }
          }
    
          return result;
        }
    
        private bool AllreadyAdded(PropertyInfo p, object obj)
        {
          var val = TryGetValue(p, obj);
          return _processedObjects.Contains(val == null ? 0 : val.GetHashCode());
        }
    
        private static object TryGetValue(PropertyInfo p, object obj)
        {
          var parameters = p.GetIndexParameters();
          if (parameters.Length == 0)
          {
            return p.GetValue(obj, null);
          }
          else
          {
            //cant serialize these
            return null;
          }
        }
    
        private static object TryGetStringValue(PropertyInfo p, object obj)
        {
          if (p.GetIndexParameters().Length == 0)
          {
            var val = p.GetValue(obj, null);
            return val;
          }
          else
          {
            return string.Empty;
          }
        }
    
        public override IEnumerable<Type> SupportedTypes
        {
          get
          {
            var types = new List<Type>();
    
            //ef types
            types.AddRange(Assembly.GetAssembly(typeof(DbContext)).GetTypes());
            //model types
            types.AddRange(Assembly.GetAssembly(typeof(BaseViewModel)).GetTypes());
    
    
            return types;
    
          }
        }
      }
    

    You can now safely make a call like new EFJavaScriptSerializer().Serialize(obj)

    Update : since version Telerik v1.3+ you can now override the GridActionAttribute.CreateActionResult method and hence you can easily integrate this Serializer into specific controller methods by applying your custom [GridAction] attribute:

    [Grid]
    public ActionResult _GetOrders(int id)
    { 
       return new GridModel(Service.GetOrders(id));
    }
    

    and

    public class GridAttribute : GridActionAttribute, IActionFilter
      {    
        /// <summary>
        /// Determines the depth that the serializer will traverse
        /// </summary>
        public int SerializationDepth { get; set; } 
    
        /// <summary>
        /// Initializes a new instance of the <see cref="GridActionAttribute"/> class.
        /// </summary>
        public GridAttribute()
          : base()
        {
          ActionParameterName = "command";
          SerializationDepth = 1;
        }
    
        protected override ActionResult CreateActionResult(object model)
        {    
          return new EFJsonResult
          {
           Data = model,
           JsonRequestBehavior = JsonRequestBehavior.AllowGet,
           MaxSerializationDepth = SerializationDepth
          };
        }
    }
    

    and finally..

    public class EFJsonResult : JsonResult
      {
        const string JsonRequest_GetNotAllowed = "This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.";
    
        public EFJsonResult()
        {
          MaxJsonLength = 1024000000;
          RecursionLimit = 10;
          MaxSerializationDepth = 1;
        }
    
        public int MaxJsonLength { get; set; }
        public int RecursionLimit { get; set; }
        public int MaxSerializationDepth { get; set; }
    
        public override void ExecuteResult(ControllerContext context)
        {
          if (context == null)
          {
            throw new ArgumentNullException("context");
          }
    
          if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
              String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
          {
            throw new InvalidOperationException(JsonRequest_GetNotAllowed);
          }
    
          var response = context.HttpContext.Response;
    
          if (!String.IsNullOrEmpty(ContentType))
          {
            response.ContentType = ContentType;
          }
          else
          {
            response.ContentType = "application/json";
          }
    
          if (ContentEncoding != null)
          {
            response.ContentEncoding = ContentEncoding;
          }
    
          if (Data != null)
          {
            var serializer = new JavaScriptSerializer
            {
              MaxJsonLength = MaxJsonLength,
              RecursionLimit = RecursionLimit
            };
    
            serializer.RegisterConverters(new List<JavaScriptConverter> { new EFJsonConverter(MaxSerializationDepth) });
    
            response.Write(serializer.Serialize(Data));
          }
        }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am working in a student group with several other people. We would like
In several pieces of sample objective-c code I've seen people create new objects like
I'd like to create several modules that will be used in nearly all scripts
I am writing a C++ application and would like to request several data files
I have URLs like http://example.com/depict?smiles=CO&width=200&height=200 (and with several other optional arguments) My urls.py contains:
I have a table with weekly data that looks like: userID Site date ------
I've seen other people mention several types of testing on Stack Overflow. The ones
I would like to hear other people's advice on when one should build a
I've recently seen several people doing things like this here on Stackoverflow: class A:
I've recently seen several people doing things like this here on Stackoverflow: class A:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.