Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create JSON with C# Object

I am trying to create the following JSON data:

{
'chart.labels': ['Bob','Lucy','Gary','Hoolio'],
'chart.tooltips': ['Bob did well',
               'Lucy had her best result',
               'Gary - not so good',
               'Hoolio had a good start'
              ]
}

I am using C# and trying to create an object in order to do this.....something like:

public class chart{
 public string[] chart.labels {get;set;}
 public string[] chart.tooltips {get;set;}
}

but obviously I cannot have properties containing spaces.

How would I go about doing this ?

UPDATE:

Using JamieC's answer the following works perfecly

public virtual ActionResult CompanyStatus()
    {
        var labelList = new List<string>() { "Bob", "Lucy", "Gary", "Hoolio" };
        var tooltipsList = new List<string>() { "Bob did well", "Lucy had her best result", "Gary - not so good", "Hoolio had a good start" };

        var cData = new chartData()
        {
            Labels = labelList.ToArray(),
            Tooltips = tooltipsList.ToArray()
        };

        var serializer = new DataContractJsonSerializer(cData.GetType());
        String output;
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, cData);
            output = Encoding.Default.GetString(ms.ToArray());
        } 

        return this.Content(output);
    }


    [DataContract]
    public class chartData
    {
        [DataMember(Name = "chart.labels")]
        public string[] Labels { get; set; }

        [DataMember(Name = "chart.tooltips")]
        public string[] Tooltips { get; set; }

    }
}

Which produces:

{"chart.labels":["Bob","Lucy","Gary","Hoolio"],"chart.tooltips":["Bob did well","Lucy had her best result","Gary - not so good","Hoolio had a good start"]}
like image 489
Mad Eddie Avatar asked Dec 19 '12 14:12

Mad Eddie


2 Answers

The usual way to do this is to use a DataContractJsonSerializer to turn your object into Json, and use DataMember attributes to annotate what names to use for properties:

[DataContract]
public class ChartModel{
 [DataMember(Name = "chart.labels")]
 public string[] Labels {get;set;}
 [DataMember(Name = "chart.tooltips")]
 public string[] Tooltips {get;set;}
}

I personally use my own ActionResult to wrap up the serialization in MVC:

public class JsonDataContractResult : ActionResult
{
    public JsonDataContractResult(Object data)
    {
        this.Data = data;
    }

    protected JsonDataContractResult()
    {

    }

    public Object Data { get; private set; }

    public override void ExecuteResult(ControllerContext context)
    {
        Guard.ArgumentNotNull(context, "context");

        var serializer = new DataContractJsonSerializer(this.Data.GetType());
        String output; 
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, this.Data);
            output = Encoding.Default.GetString(ms.ToArray());
        } 
        context.HttpContext.Response.ContentType = "application/json";
        context.HttpContext.Response.Write(output);
    }        
}

And return that from a helper method in a base controller:

public abstract class MyBaseController: Controller
{

    protected JsonDataContractResult JsonContract(Object data)
    {
        return new JsonDataContractResult(data);
    }

}

Then my controller becomes really simple:

public class SomeController: MyBaseController
{
    public ActionResult SomeAction()
    { 
        var model = new ChartModel()
                   { 
                       Labels = ..., 
                       Tooltips = ... 
                   };
        return JsonContract(model);
    }
}
like image 91
Jamiec Avatar answered Oct 21 '22 03:10

Jamiec


You can use JSON.NET library, you can download it from here

It has this feature:

Attribute property name customization

This question will help you:

Json.Net: JsonSerializer-Attribute for custom naming

And you can use DataContractJsonSerializer it provides this feature, but JavaScriptSerializer is not.

like image 39
Sawan Avatar answered Oct 21 '22 04:10

Sawan