Returning datatable cast as object from web service causes Circular Reference error

  1. #1

    Returning datatable cast as object from web service causes Circular Reference error

    Hello,

    I'm using a Store, JsonReader, and GridPanel. I'm using the HttpProxy of the store to call a webservice. I got this working just fine in an example, but when I switched the data from the hard-coded List<object> used in the examples to a datatable, I got the following error:
    A circular reference was detected while serializing an object of type \u0027System.Reflection.Module\u0027
    I have a DataTable dt that is filled with information. I then cast it as the proper return type expected, Paging<object>:

    IEnumerable<DataRow> iEnumData = dt.AsEnumerable();
    IEnumerable<object> iEnumObj = iEnumData.Cast<object>();
    Paging<object> pagingObj = new Paging<object>(iEnumObj, intTotalRows));
    return pagingObj
    I know that the circular reference is caused by the json serialization of the ADO.NET objects (DataTable and DataRows), but I thought since I was casting it, the problem would be fixed. I know that I could just create a class and do a manual conversion from DataTable to class, then returning the Paging<MyNewClass>, but these DataTables are dynamic. This one call retrieves different structures. Any thoughts?


  2. #2

    RE: Returning datatable cast as object from web service causes Circular Reference error

    Just to describe my progress, or lack thereof...

    My intention was to find a way to convert a DataTable into some kind of IEnumerable<object> that could be:
    1. Put into the Paging<object> instance's Data property WITHOUT requiring knowledge of the underlying structure of the DataTable before runtime
    2. Returned (from within the Paging<object> instance) and json serialized properly

    I had to abandon the idea of accomplishing this dynamically. Instead, for each grid I had I created a class (called MyGridClass below) and then a converter method for each class to convert the DataTable into a List<object> (with object's underlying type actually being MyGridClass in this example).

    public static List<object> ConvertDataTable(DataTable dt)
            {
                List<object> lstDataRows = new List<object>();
                foreach (DataRow dr in dt.Rows)
                {
                    MyGridClass row = new MyGridClass
                    {
                        Column1 = Convert.ToInt32(dr["Column1"]),
                        Column2 = ConverterClass.ToNullableDateTime(dr["Column2"]),
                        Column3 = Convert.ToString(dr["Column3"])
                    };
                    lstDataRows.Add(row);
                }
                return lstDataRows;
            }
    If anyone knows a better way, please let me know. I really didn't want to do it this way, just couldn't think of an alternative.
  3. #3

    RE: Returning datatable cast as object from web service causes Circular Reference error

    I am running into this exact issue too. If I change the Proxy to a PageProxy, I can set the store's datasource to a datatable. How can I do the same with a HttpHandler?
  4. #4

    RE: Returning datatable cast as object from web service causes Circular Reference error

    Hi,

    If you use PageProxy then request goes to the page where described the store. In this case the store's Fields can be used during serialization (serialization by field)


    If you use HttpProxy then store is inaccessable therefore complex serialization is used (whole object will be serialized). Therefore i can suggest convert datatable to appropriate format which has no circullar reference or write own serialization (return own json) like
    context.Response.ContentType = "text/json";
    context.Response.Write(string.Format("{{'data':{0}}}", MySerializeMethod(MyDataTable)));

    Don't foget to set 'Root' for the JsonReader (Root="data")
  5. #5

    RE: Returning datatable cast as object from web service causes Circular Reference error

    I notice that Ext.Net.JSON.Serialize can serialize a datatable correctly if given the datatable itself but not if given the rows or datatable.AsEnumerable(). So I created my own ReturnData object that is similar to your Paging List object and serialized that instead. Worked like a charm.

        Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "text/json"
    
    
            Dim start = WebUtils.GetRequestInt(context.Request, "start")
            Dim limit = WebUtils.GetRequestInt(context.Request, "limit", 50)
            Dim sort = WebUtils.GetRequestString(context.Request, "sort")
            Dim dir = WebUtils.GetRequestString(context.Request, "dir")
            Dim guid = WebUtils.GetRequestGUID(context.Request, "widgetGUID")
    
    
            Dim widget = FindWidget(guid)
            Dim widgetUI = TryCast(Widgets.WidgetFactory.GetWidgetUI(widget), Widgets.GridBase)
    
    
            If widgetUI Is Nothing Then Exit Sub
    
    
            Dim total As Integer = 0
            Dim data = widgetUI.GetData(start, limit, sort, dir, total) 'TODO: fix direction
    
    
            Dim returnData As New ReturnData(data, total)
            context.Response.Write(Ext.Net.JSON.Serialize(returnData))
    
    
        End Sub
    
    
        Public Class ReturnData
    
    
            Private _Data As Object = Nothing
            Public Property Data() As Object
                Get
                    Return _Data
                End Get
                Set(ByVal value As Object)
                    _Data = value
                End Set
            End Property
    
    
            Private _TotalRecords As Integer = 0
            Public Property TotalRecords() As Integer
                Get
                    Return _TotalRecords
                End Get
                Set(ByVal value As Integer)
                    _TotalRecords = value
                End Set
            End Property
    
    
            Public Sub New()
    
    
            End Sub
    
    
            Public Sub New(ByVal data As Object, ByVal totalrecords As Integer)
                Me.Data = data
                Me.TotalRecords = totalrecords
            End Sub
    
    
        End Class


Similar Threads

  1. Replies: 1
    Last Post: Jun 27, 2012, 9:19 PM
  2. Replies: 1
    Last Post: Sep 13, 2011, 5:19 PM
  3. ServerMapping returning [object Object]
    By DavidS in forum 1.x Help
    Replies: 13
    Last Post: Jun 14, 2011, 6:19 AM
  4. Replies: 0
    Last Post: Jun 03, 2009, 4:18 AM
  5. [CLOSED] Ext Object Reference
    By Ben in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Jan 08, 2009, 7:03 PM

Posting Permissions