This is a migrated thread and some comments may be shown as answers.

[Solved] Binding to DataTable: A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.

12 Answers 329 Views
Chart
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
John
Top achievements
Rank 1
John asked on 16 May 2012, 06:24 PM
I need to bind my MVC Chart control to a DataTable.  Does the control support this? 

I started a new MVC3 project, and this is the contents of my Index.cshtml file:

@using Telerik.Web.Mvc.UI
@using System.Data
@using System.Linq
 
@{
    ViewBag.Title = "Home Page";
    DataTable table = ViewBag.Table as DataTable;
}
 
<h2>@ViewBag.Message</h2>
<p>
@(Html.Telerik().Chart(table.Rows.OfType<DataRow>()).Name("Chart1"))
</p>

This is my _Layout.cshtml file:

@using Telerik.Web.Mvc.UI
 
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    @(Html.Telerik().StyleSheetRegistrar().DefaultGroup(g => g.Add("telerik.common.css").Add("telerik.default.min.css")))
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
</head>
<body>
    <div class="page">
        <header>
            <div id="title">
                <h1>My MVC Application</h1>
            </div>
            <div id="logindisplay">
                @Html.Partial("_LogOnPartial")
            </div>
            <nav>
                <ul id="menu">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                </ul>
            </nav>
        </header>
        <section id="main">
            @RenderBody()
        </section>
        <footer>
        </footer>
    </div>
    @Html.Telerik().ScriptRegistrar()
</body>
</html>

And finally, my HomeController.cs:

public class HomeController : Controller {
        public ActionResult Index() {
            ViewBag.Message = "Welcome to ASP.NET MVC!";
            DataTable table = new DataTable("Blah");
            table.Columns.AddRange(new DataColumn[] {
                new DataColumn("Col1", typeof(string)),
                new DataColumn("Col2", typeof(int)) });
            table.Rows.Add("Test", 5);
            table.Rows.Add("Test2", 53);
            table.Rows.Add("Test3", 215);
            table.Rows.Add("Test4", 15);
            table.Rows.Add("Test5", 2);
                 
            ViewBag.Table = table;
 
            return View();
        }
 
        public ActionResult About() {
            return View();
        }
    }

When I run this, I get the following error:

A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.

Source Error: 

Line 33:         </footer>
Line 34:     </div>
Line 35:     @Html.Telerik().ScriptRegistrar()
Line 36: </body>
Line 37: </html>

Source File: c:\temp\MvcApplication2\MvcApplication2\Views\Shared\_Layout.cshtml    Line: 35 

Stack Trace: 

[InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.]
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1478
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +26
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +74
   Telerik.Web.Mvc.UI.ClientSideObjectWriter.AppendObject(String name, Object value) +100
   Telerik.Web.Mvc.UI.Chart`1.SerializeDataSource(IClientSideObjectWriter objectWriter) +112
   Telerik.Web.Mvc.UI.Chart`1.WriteInitializationScript(TextWriter writer) +634
   Telerik.Web.Mvc.UI.ScriptRegistrar.WriteScriptStatements(TextWriter writer) +671
   Telerik.Web.Mvc.UI.ScriptRegistrar.Write(TextWriter writer) +34
   Telerik.Web.Mvc.UI.ScriptRegistrar.ToHtmlString() +65
   Telerik.Web.Mvc.{Dynamic}.ScriptRegistrarBuilder.IHtmlString.ToHtmlString() +12
   System.Web.HttpUtility.HtmlEncode(Object value) +38
   System.Web.WebPages.WebPageBase.Write(Object value) +64
   ASP._Page_Views_Shared__Layout_cshtml.Execute() in c:\temp\MvcApplication2\MvcApplication2\Views\Shared\_Layout.cshtml:35
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +88
   System.Web.WebPages.<>c__DisplayClass7.<RenderPageCore>b__6(TextWriter writer) +102
   System.Web.WebPages.HelperResult.WriteTo(TextWriter writer) +12
   System.Web.WebPages.WebPageBase.Write(HelperResult result) +67
   System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body) +66
   System.Web.WebPages.WebPageBase.PopContext() +262
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +95
   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
   System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
   System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8836913
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
 

Am I doing something wrong?  Again, all I need to do is bind my MVC Chart control to a DataTable.  Does the control support this? 

12 Answers, 1 is accepted

Sort by
0
T. Tsonev
Telerik team
answered on 19 May 2012, 08:48 AM
Hello,

The Chart requires a serializable model as the rendering happens on the client-side. The DataTable is not directly serializable as it contains circular references. You need to convert it to a serializable type. For example, a dictionary:

public ActionResult Index()
{
    DataTable table = new DataTable("Blah");
    table.Columns.AddRange(new DataColumn[] {
        new DataColumn("Col1", typeof(string)),
        new DataColumn("Col2", typeof(int)) });
    table.Rows.Add("Test", 5);
    table.Rows.Add("Test2", 53);
    table.Rows.Add("Test3", 215);
    table.Rows.Add("Test4", 15);
    table.Rows.Add("Test5", 2);

    return View(SerializeTable(table));
}

private IEnumerable<Dictionary<string, object>> SerializeTable(DataTable table)
{
    return table.DefaultView.OfType<DataRowView>().Select(row =>
    {
        var result = new Dictionary<string, object>();
        foreach (DataColumn column in table.Columns)
        {
            result.Add(column.ColumnName, row.Row[column.ColumnName]);
        }

        return result;
    });
}


I hope this helps.

Regards,
Tsvetomir Tsonev
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Viktor
Top achievements
Rank 1
answered on 21 May 2012, 05:57 PM
I try to do the same staff and have a problem to bind columns to the series. Please send some example.
0
T. Tsonev
Telerik team
answered on 23 May 2012, 04:25 PM
Hi,

I can confirm that binding series to a dictionary does not work. We'll look into that.

For the moment, you can try mapping fields manually to a static or dynamic type:
public ActionResult Index()
{
    DataTable table = new DataTable("Blah");
    table.Columns.AddRange(new DataColumn[] {
        new DataColumn("Category", typeof(string)),
        new DataColumn("Value", typeof(int)) });
    table.Rows.Add("Test", 5);
    table.Rows.Add("Test2", 53);
    table.Rows.Add("Test3", 215);
    table.Rows.Add("Test4", 15);
    table.Rows.Add("Test5", 2);


    return View(SerializeTable(table));
}

private IEnumerable<dynamic> SerializeTable(DataTable table)
{
    return table.DefaultView.OfType<DataRowView>().Select(row =>
    {
        return new
        {
            Category = row.Row["Category"],
            Value = row.Row["Value"]
        };
    });
}


----

@(Html.Telerik().Chart(Model)
      .Name("chart")
      .Series(series => {
          series.Area("Value");
      })
      .CategoryAxis(axis => axis
          .Categories("Category")
      )
      .HtmlAttributes(new { style = "width: 600px; height: 400px;" })
)


I hope this helps. Kind regards,
Tsvetomir Tsonev
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Viktor
Top achievements
Rank 1
answered on 23 May 2012, 06:28 PM
Thank you,

It works but in my case in my datatable  I don't know columns name and number of columns.
Please help.

Thank you,

Viktor
0
Accepted
T. Tsonev
Telerik team
answered on 29 May 2012, 06:25 AM
Hi,

This does not leave us any choice, but to build the series dynamically.

.Series(series =>
{
    foreach (DataColumn column in Model.Columns)
    {
        if (column.DataType == typeof(int))
        {
            series.Area(Model.DefaultView.OfType<DataRowView>().Select(
                row => row[column.ColumnName]
            ))
            .Name(column.ColumnName);
        }
    }
})


See the attached project.

We will try to enable binding to dictionary in the future versions.  All the best,
Tsvetomir Tsonev
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
John
Top achievements
Rank 1
answered on 30 May 2012, 06:56 PM
This worked perfectly!  Thank you so much.
0
Viktor
Top achievements
Rank 1
answered on 01 Jun 2012, 04:14 PM
Hi,

You example working fine for one column. But when I create more then one column the graph show them the same but datatable has different value for each column.

 public ActionResult TestGraph3()
        {


           
            DataTable table = new DataTable("Blah");
            table.Columns.AddRange(new DataColumn[] {
                new DataColumn("Category", typeof(string)),
                new DataColumn("Value1", typeof(int)),
            new DataColumn("Value2", typeof(int)),new DataColumn("Value3", typeof(int))});
            table.Rows.Add("Test", 5,6,7);
            table.Rows.Add("Test2", 53,87,75);
            table.Rows.Add("Test3", 215,250,240);
            table.Rows.Add("Test4", 15,25,15);
            table.Rows.Add("Test5", 2,78,14);
            // ViewBag.Table = SerializeTable(dt);
            return View(table);


        }

Please help.


Thank you,

Viktor

0
John
Top achievements
Rank 1
answered on 04 Jun 2012, 05:10 AM
Hmmm.  How do I add a "Category" to a pie series when I build the series dynamically?  I tried this but there's no category labels on the pie:

@(Html.Telerik().Chart()
    .Name("PieChart")
    .Legend(legend => legend
        .Visible(Model.ShowLegend)
        .Position(Model.LegendPosition.Convert<ChartLegendPosition>())
    )
    .Series(series => series
        .Pie(Model.Node.Table.DefaultView.OfType<DataRowView>().Select(row => row[Model.ValueMemberName]))        
    )
    .CategoryAxis(axis => axis.Categories(Model.Node.Table.DefaultView.OfType<DataRowView>().Select(row => row[Model.CategoryMemberName])))
    .Tooltip(true)
)
0
Hristo Germanov
Telerik team
answered on 06 Jun 2012, 07:33 AM
Hi John,

1) Unfortunately the pie chart has no category axis and I will try to remove this builder.
2) You can't pass dynamically category labels for the pie chart. We will try to fix this issue too. 

Please excuse us for the inconvenience.

Greetings,
Hristo Germanov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
John
Top achievements
Rank 1
answered on 12 Jun 2012, 03:27 PM
Thanks Hristo.  How would I set the legend then?
0
Hristo Germanov
Telerik team
answered on 13 Jun 2012, 07:14 AM
Hello Jonn,

Can you try this:

@(Html.Telerik().Chart()
    .Name("PieChart")
    .Legend(legend => legend
        .Visible(Model.ShowLegend)
        .Position(Model.LegendPosition.Convert<ChartLegendPosition>())
    )
    .Series(series =>
    {
        var data = from drv in Model.Node.Table.DefaultView.OfType<DataRowView>()
                   select new
                   {
                       value = drv.Row[Model.ValueMemberName],
                       category = drv.Row[Model.CategoryMemberName]
                   });
        series.Pie(data);
    )
    .Tooltip(true)
)

All the best,
Hristo Germanov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Tundey
Top achievements
Rank 1
answered on 26 Dec 2012, 05:07 PM
In Index.cshtml, replace

foreach (DataColumn column in Model.Columns)
      {
        if (column.DataType == typeof(int))
        {
          series.Column(Model.DefaultView.OfType<DataRowView>().Select(
              row => row[column.ColumnName]
          ))
          .Name(column.ColumnName).Stack(true);
        }
      }

with

        for (int i = 1; i <= Model.Columns.Count; i++)
        {
          var column = Model.Columns[i - 1];
          if (column.DataType == typeof(int))
          {
            series.Column(Model.DefaultView.OfType<DataRowView>().Select(
                  row => row[column.ColumnName]
              ))
              .Name(column.ColumnName);
          }
        }

I ran into a similar problem working with the Grid control and the solution was here: http://stackoverflow.com/questions/11472946/telerik-mvc-grid-with-dynamic-columns-at-run-time-from-a-collection-or-dictionar/11475166#11475166

Thanks,
Tundey

Tags
Chart
Asked by
John
Top achievements
Rank 1
Answers by
T. Tsonev
Telerik team
Viktor
Top achievements
Rank 1
John
Top achievements
Rank 1
Hristo Germanov
Telerik team
Tundey
Top achievements
Rank 1
Share this question
or