1

I have a graph in my view which looks like this:

  var hourlyGraph = Morris.Bar({
            element: 'graph_bar',
            data: [
               @foreach (var item in ViewBag.HourlyGraph)
               {
                @:{device: '@item.Hour.ToString("D2"):00', geekbench:@item.Sales },
               }
            ],
            xkey: 'device',
            ykeys: ['geekbench'],
            labels: ['Sold'],
            barRatio: 0.4,
            barColors: ['#0A4D70', '#34495E', '#ACADAC', '#3498DB'],
            xLabelAngle: 35,
            hideHover: 'auto',
            resize: true
      });

This is a morris chart. Note how the data is set up here:

[
@foreach (var item in ViewBag.HourlyGraph)
{
@:{device: '@item.Hour.ToString("D2"):00', geekbench:@item.Sales },
}
]

And now I need to fill the chart with new data. In my Action I have created a list which contains 2 properties:

public int Hour {get;set;}
public int Sales {get;set;}

And they are stored into a list typed of:

var HourlyGraph = new List<HourlyGraph>();

Now I'd like to convert this list into a JSON format which would look something like this:

[
{device: '0', geekbench:5 },
{device: '1', geekbench:13 },
{device: '2', geekbench:25 },
{device: '3', geekbench:14 },
{device: '4', geekbench:16 },
]

Where value for device would be = hour, and geekbench = sales ...

How could I do this in C#?

User987
  • 3,663
  • 15
  • 54
  • 115
  • Something like this would work ? new JavaScriptSerializer().Deserialize(yourList); – Joab Santos Mar 14 '17 at 14:11
  • Did you have a look at the Newtonsoft.JSON library? You will find it on nuget – Tom Doodler Mar 14 '17 at 14:11
  • @TomDoodler yes but what confuses me here is how do I set the first string in json to be named like "device" and "geekbench" ? – User987 Mar 14 '17 at 14:12
  • @joab what about "device" and "geekbench" values, how do I place them in JSON response ? – User987 Mar 14 '17 at 14:13
  • Somethin like this would work ? [JsonProperty(PropertyName = "device")] public int Hour {get;set;} – Joab Santos Mar 14 '17 at 14:15
  • You can project to an anonymous object with the property names you want, e.g. `HourlyGraph.Select(hg => new { device = hg.Hour.ToString(), geekbench = hg.Sales });` – stuartd Mar 14 '17 at 14:16
  • @joab done , but for the first part of code it says cannot convert type HourlyGraph into string ? – User987 Mar 14 '17 at 14:17
  • Using the Newtonsoft.JSON , look at this http://stackoverflow.com/questions/35654350/converting-list-of-objects-to-json-array – Joab Santos Mar 14 '17 at 14:19

3 Answers3

2

With Json.Net and Linq it's easy:

string myJson = 
   JsonConvert.SerializeObject(mylist.Select(item=>
                                  new {device=item.Hour, geekbench=item.Sales}));

You project an anonymous type with the fields and names that you'd like, and let Newtonsoft.Json do the rest.

Ofir Winegarten
  • 9,215
  • 2
  • 21
  • 27
  • Ofir, this is NewtonSoft.JSON library , no ? It says it doesn't contains method "Serialize" ... ? – User987 Mar 14 '17 at 14:21
  • 1
    it's SerializeObject sorry – Ofir Winegarten Mar 14 '17 at 14:22
  • Ofir, another quick question, says i.Sales doens't exists ... ? Should it be item.Sales or ? – User987 Mar 14 '17 at 14:24
  • ohhh me and my typos... sure it's item – Ofir Winegarten Mar 14 '17 at 14:25
  • haha happens , thx a lot =D .. Btw. return type of this action should be string or JsonResponse? Or just a simple string ? – User987 Mar 14 '17 at 14:26
  • Ofir , oh my goodness I'm missing just one small thing.. The response is returned like this: [{"device":"16","geekbench":1}] ... Device is under two quote marks but it shouldn't be... it should be just like this: [{device:"16","geekbench":1}] – User987 Mar 14 '17 at 14:31
  • Well, i'm no expert on MVC. this one will just be a string, but if you need a JsonResponse i guess you need to add the header: return this.Content(jsonString, "application/json"); also maybe the answer from Usman mixing with the Linq projection would give you the best resutls – Ofir Winegarten Mar 14 '17 at 14:34
  • Why shouldn't it be with quotes? that's a correct json syntax – Ofir Winegarten Mar 14 '17 at 14:35
  • Ofir, for some reason this graph doesn't uses quotes for the property... Not sure why =/ – User987 Mar 14 '17 at 14:37
1

since you are using mvc why not use return Json() it will convert the object to json string you can use it like

  public ActionResult Myaction()
    { 
        var HourlyGraph = new List<HourlyGraph>();


        return Json(HourlyGraph.Select(x => new {Hour=x.Hour,Sales=x.Sales }));
    }
Usman
  • 4,615
  • 2
  • 17
  • 33
0

You can achieve the desired output by using LINQ Anonymous Type

As per example following is class

public class HourlyGraph
{
    public int Hour { get; set; }
    public int Sales { get; set; }
}

Import Namespace System.Web.Script.Serialization which is a Microsoft's Inbuilt Class for dealing with JSON. You will need to refer additional assembly named System.Web.Extensions using 'Add References'.

using System.Web.Script.Serialization;

Declare List and Convert into customized JSON Format

        var listHourlyGraph = new List<HourlyGraph>();

        //Adding some Sample Values
        listHourlyGraph.Add(new HourlyGraph() { Hour = 0, Sales = 5 });
        listHourlyGraph.Add(new HourlyGraph() { Hour = 1, Sales = 10 });

        //Declaring JavaScriptSerialzer Object
        var serialzer = new JavaScriptSerializer();

        //Using Serialize Method which returns back a JSON String
        //We are using LINQ SELECT Method to create a new anonymous return type which contains our custom return types
        string s = serialzer.Serialize(listHourlyGraph.Select(x => new { device = x.Hour, geekbench = x.Sales } ));

You will get the following output in 's' variable

[{"device":0,"geekbench":5},{"device":1,"geekbench":10}]

Note: If you want to get performance optimizations then you are better using Newtonsoft JSON Library instead of Microsoft's Default JSON Library.

vibs2006
  • 6,028
  • 3
  • 40
  • 40
  • Also to add if you want the JSON values as string rather than integer then use C#'s ToString() method in anoumous type. e.g string s = serialzer.Serialize(listHourlyGraph.Select(x => new { device = x.Hour.ToString(), geekbench = x.Sales.ToString() } )); – vibs2006 Mar 14 '17 at 16:02