1

i want chart on Results Page. i have a class Results

    using System;

namespace PersonalArea.DAL.Models
{
    public class Result
    {
        public string Id { get; set; }

        public string PatientId { get; set; }

        public string GameName { get; set; }

        public string Time { get; set; }

        public int Score { get; set; }

        public int Level { get; set; }

        public DateTime FirstEnter { get; set; }

        public DateTime DateEnter { get; set; }

        public DateTime DateExit { get; set; }

        public string DifficultLevel { get; set; }

        public virtual Patient Patient { get; set; }
    }
}

In PatientController has a some method

[HttpGet]
    public async Task<IActionResult> Results(string id)
    {
        if (string.IsNullOrEmpty(id))
        {
            return NotFound();
        }
        Patient patient = await _userManager.FindByIdAsync(id) as Patient;
        if (patient == null)
        {
            return NotFound();
        }
        IQueryable<IGrouping<string, Result>> results = _context.Results.Where(x => x.PatientId == id).GroupBy(z => z.GameName);
        return View(results);
    }

And in Results.cshtml have a some code:

@model IQueryable<IGrouping<string, PersonalArea.DAL.Models.Result>>
@inject IJsonHelper Json;

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
    <title>Index</title>
</head>
<body>
    <div id="chartContainer"></div>

    <script type="text/javascript">
        var model = @Html.Raw(Json.Serialize(Model));
        var datapoints = [];
        // build an array of objects
        $.each(model, function(index, item) {
    datapoints.push({ x: new Date(item.DateEnd), y: item.scores });


  window.onload = function () {
   var chart = new CanvasJS.Chart("chartContainer", {
    theme: "theme2",
    animationEnabled: true,
    title: {
     text: "Simple Column Chart in ASP.NET MVC"
    },
    subtitles: [
     { text: "Try Resizing the Browser" }
    ],
    data: [
    {
                        type: "column", //change type to bar, line, area, pie, etc
                        dataPoints: datapoints
                    /*[
     { x: 10, y: 71 },
     { x: 20, y: 55 },
     { x: 30, y: 50 },
     { x: 40, y: 65 },
     { x: 50, y: 95 },
     { x: 60, y: 68 },
     { x: 70, y: 28 },
     { x: 80, y: 34 },
     { x: 90, y: 14 }
     ]*/
                                        //Uncomment below line to add data coming from the controller.
     //dataPoints: @Html.Raw(ViewBag.DataPoints),
    }
    ]
   });
   chart.render();
  };
    </script>

</body>
</html> 

But system have error:

An unhandled exception occurred while processing the request.

JsonSerializationException: Self referencing loop detected with type 'PersonalArea.DAL.Models.Result'. Path '[0][0].patient.results'.

Please, help my resolve this error

Travis Bincle
  • 61
  • 1
  • 9
  • You might have a look at my answer on **[“Self Referencing Loop Detected” exception with JSON.Net](https://stackoverflow.com/questions/40472419/self-referencing-loop-detected-exception-with-json-net/51235783#51235783)** page. – Murat Yıldız Jul 08 '18 at 20:37

2 Answers2

0

You can change the Newtonsoft.Json configuration to ignore self-referecing loops like this:

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
= Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

Or you can do this only in the serilization call:

JsonConvert.SerializeObject(objectToSerialize, Formatting.Indented, 
new JsonSerializerSettings { 
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});

You have these options:

  • ReferenceLoopHandling.Error This is the default, will raise an error if a reference loop is detected. This is why you get an exception.
  • ReferenceLoopHandling.Serialize is useful if objects are nested but not indefinitely.
  • ReferenceLoopHandling.Ignore will not serialize an object if it is a child object of itself.
Luís Antunes
  • 326
  • 2
  • 9
  • And where i can use it? – Travis Bincle Mar 12 '18 at 15:42
  • What’s happening in the code above is that in your DAL Model you have a self referencing loop, meaning some of your Parient properties is a Result object or something similar. When you serialize the Model in the view it throws an exception. In this code you should use the options I wrote above, meaning you should pass another parameter with the serialization options. – Luís Antunes Mar 13 '18 at 06:52
  • Another thing, a better approach than sending DAL objects to the View is using Viewmodels, where only the information the view needs is sent. You can use for example AutoMapper to do the job of converting the two model objects. – Luís Antunes Mar 13 '18 at 06:55
0
[HttpGet]
    public async Task<IActionResult> Results(string id)
    {
        if (string.IsNullOrEmpty(id))
        {
            return NotFound();
        }
        Patient patient = await _userManager.FindByIdAsync(id) as Patient;
        if (patient == null)
        {
            return NotFound();
        }
        list<Result> query = _context.Results.Where(x => x.PatientId == id).GroupBy(z => z.GameName).ToList();
ViewBag.Test = JsonConvert.SerializeObject(query);
        return View(results);

View.chtml in

 <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
    <div id="chartContainer" style="height: 400px;"></div>

    <script type="text/javascript">
        window.onload = function ()
        {
            var test = @Html.Raw(ViewBag.test);
            var datapoints = [];

     for (var i = 0; i < test.length; i++) {
                datapoints.push({ y: test[i].Score, x: test[i].ID, label: test[i].GameName });
            }
window.onload = function () {
            var chart = new CanvasJS.Chart("chartContainer", {
                theme: "theme2",
                animationEnabled: true,
                title: {
                    text: "Simple Column Chart in ASP.NET MVC"
                },
                subtitles: [
                    { text: "Try Resizing the Browser" }
                ],
                data: [
                {
                        type: "column", //change type to bar, line, area, pie, etc
                        dataPoints: datapoints
                    /*[
                    { x: 10, y: 71 },
                    { x: 20, y: 55 },
                    { x: 30, y: 50 },
                    { x: 40, y: 65 },
                    { x: 50, y: 95 },
                    { x: 60, y: 68 },
                    { x: 70, y: 28 },
                    { x: 80, y: 34 },
                    { x: 90, y: 14 }
                    ]*/
                                        //Uncomment below line to add data coming from the controller.
                    //dataPoints: @Html.Raw(ViewBag.DataPoints),
                }
                ]
            });
            chart.render();
        };

        }
paingsoethu 2015
  • 85
  • 1
  • 1
  • 8
  • I tryed write code in Contoller like this List query = _context.Results.Where(x => x.PatientId == id).GroupBy(z => z.GameName).ToList(); but a have error "Cannot convert type from System.Linq.IGrouping to list". What can i do? – Travis Bincle Mar 12 '18 at 11:54
  • So this https://stackoverflow.com/a/49234780/9478131 i told about new problem, please, tell me, what can i do? – Travis Bincle Mar 12 '18 at 15:20