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#?
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.
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 }));
}
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.
Related
I am working on a C# app to work with a 3rd party vendor. They've requested that our JSON be formatted as such (note the "owner" array value)
var good =
{
"id": "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
"make": "Subaru",
"index": "Forester",
"year": "2013",
"owner":
[
{
"First": "Bob",
"Last": "Smith"
}
]
}
In my code, I am unable to get the formatting correct. I am able to produce valid C#, but it doesn't add "owner" as an array and any attempt to make it an array (e.g. adding "[]" after the "new" produces an error ("The name 'x' does not exist in the current context"). Here is my attempted C# code:
var car = new
{
id = "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
make = "Subaru",
model = "Forester",
year = "2013",
Owner = new
{
First = "Bob",
Last = "Smith"
}
};
I tried making a "Car" class and tried using an anonymous type.
Your JSON field for owner is an array and in your code you assign it as an object so you need to assign owner to an array like below:
var car = new
{
id = "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
make = "Subaru",
model = "Forester",
year = "2013",
Owner = new[]
{
new { First = "Bob", Last = "Smith" }
}
};
I want to build a dynamic class with a given JSON.
Atm i parse the json with
dynamic customConfig = JsonConvert.DeserializeObject(configJson);
and its working fine with other json then the given BUT my problem is that the names of the properties (here valueOne and valueTwo are "dynamic", i get always others)
i Know if i know the names i can get e.g. the description by customConfig.config.valueOne.description
But what can i do to get e.g. the description by dont have the name of valueOne?
configJson=
"config": {
"valueOne":{
"description": "My first example value.",
"defaultValue": "Example 1",
"isRequired":false
},
"valueTwo":{
"description": "My second example value.",
"defaultValue": "Example 2",
"isRequired":false
},
},
What i tried was to get it in a loop but i dont get it to another class.
foreach (var param in customConfig.config)
{
foreach (var item in param)
{
Config.config.description[i] = item.description;
}
i++;
}
item.description gets the right description but why i cant save it in the other class (which is also dynamic)?
You might have some other underlying logic issues with your loop and what you're trying to accomplish there, but to answer your specific question, you might need to initialize your "config" and "data" members of your CustomConfigModel class. For example...
public class CustomConfigModel
{
public CustomConfigModel()
{
this.data = new ExpandoObject();
this.config = new ExpandoObject();
}
public dynamic data { get; set; }
public dynamic config { get; set; }
}
I was able to access the description you want, I think but it is in this form (my output) :
Token key: 'config.valueOne' ->>>> 'description' : 'My first example value.'
Token key: 'config.valueTwo' ->>>> 'description' : 'My first example value.'
If you know main item name , "config", before hand , you can parse and get rid of it so that you'd have values : "valueOne" or "valueTwo". As you can see from my example code, you can get description values by iterating. You can develop further functionality from this example. Please let me know if this works for you.
Here is the example code:
class Program
{
static void Main(string[] args)
{
string configJson = #"{
'config': {
'valueOne':{
'description': 'My first example value.',
'defaultValue': 'Example 1',
'isRequired':false
},
'valueTwo':{
'description': 'My second example value.',
'defaultValue': 'Example 2',
'isRequired':false
},
}
}";
JObject customConfig = (JObject)JsonConvert.DeserializeObject(configJson);
var children = customConfig.Children().Children();
List<JToken> subList = new List<JToken>();
foreach (JToken token in children.Values())
{
string key = token.Path;
subList.AddRange(token.Values());
JToken subitem = subList.Find(q => q.Path.Contains("description"));
string desc = ((JProperty)subitem).Value.ToString();
Console.WriteLine("Token key: '" + key + "' ->>>> 'description' : '" + desc+"'");
}
}
}
At
Config.config.description[i] = item.description;
is description[i] null and i get an excception but why
I am new to C# and to RestSharp.
I am writing a small program to retrieve a list of records via REST. I have been able to retrieve one record. Now I need to get a list of records, and here I have a problem.
The response I get using SoapUI looks like this:
{
"#count": 2,
"#start": 1,
"#totalcount": 2,
"Messages": [],
"ResourceName": "email",
"ReturnCode": 0,
"content": [
{"email": {"evsysseq": "0000000000000262"}},
{"email": {"evsysseq": "0000000000000263"}}
]
}
My code looks like this:
class EmailID
{
public string Evsysseq { get; set; }
}
var client = new RestClient("xxxxx");
client.Authenticator = new HttpBasicAuthenticator("xxx", "xxx");
string queryParm = HttpUtility.UrlEncode("evsysseq>\"0000000000000261\"");
var request = new RestRequest("xxxx?query="+ queryParm, Method.GET);
request.RootElement = "content";
var queryResult = client.Execute<List<EmailID>>(request).Data;
Running it does not result in errors, and I can see on the queryResult object that it does contain two records. But, Evsysseq is null on both, and that is my problem. I am not sure what to tweak to get it right.
You are getting null values because the JSON you are deserializing does not match the class structure you are deserializing into. You are telling RestSharp to deserialize the content array into a List<EmailID>, but the JSON really represents a list of objects that contain EmailID objects. And so you need another class:
class EmailObj
{
public EmailID Email { get; set; }
}
Then deserialize like this and you should get the data:
var queryResult = client.Execute<List<EmailObj>>(request).Data;
If you want to, you can then use LINQ to get the List<EmailID> that you originally wanted like this:
var emailIds = queryResult.Select(eo => eo.Email).ToList();
HTH
I have a web application in which I'm retrieving some data into bootstrap table, what i want to do now is to use jQuery DataTable instead of the current as it has too much useful features.
Currently I'm retrieving the data from the server side using OOP approach, where a class object represents a data row in a particular table, and this object includes a dictionary which stores column names and values.
What I'm doing now is that I'm retrieving these class objects and append each dictionary of each object in a List<Item> and then serialize this list using JavaScriptSerializer object, and this object returns the following JSON format:
[
{
"slno":"2",
"status_message":"Lights still flashing",
"crm_services_id":"1", "subject_id":"Lights are flashing",
"severity_id":"5",
"user_id":"husain.alhamali",
"status_id":"1"
},
{
"slno":"3",
"status_message":"lights working fine",
"crm_services_id":"2",
"subject_id":"Lights are flashing",
"severity_id":"3",
"user_id":"husain.alhamali",
"status_id":"2"
}
]
When i tried to use this object to fill my DataTable AJAX I've got an error says:
Invalid JSON response
I saw some examples of a valid JSON response that is acceptable to a DataTable which is as follow:
{
"data": [
[
"Tiger Nixon",
"System Architect",
"Edinburgh",
"5421",
"2011/04/25",
"$320,800"
],
[
"Garrett Winters",
"Accountant",
"Tokyo",
"8422",
"2011/07/25",
"$170,750"
]
}
Now my question is is there any tool or plugin that could re-format my JSON string into an acceptable format like the one above?
With this HTML:
<table id="example"></table>
This JS will create a table:
var data = [{
"slno": "2",
"status_message": "Lights still flashing",
"crm_services_id": "1",
"subject_id": "Lights are flashing",
"severity_id": "5",
"user_id": "husain.alhamali",
"status_id": "1"
}, {
"slno": "3",
"status_message": "lights working fine",
"crm_services_id": "2",
"subject_id": "Lights are flashing",
"severity_id": "3",
"user_id": "husain.alhamali",
"status_id": "2"
}];
function getColumns(){
for(var i = 0; i < data.length; i++){
let columnsArray = [];
var keys = Object.keys(data[i]);
for(k in Object.keys(data[i])){
if(data[i].hasOwnProperty(keys[k])){
columnsArray.push({
"data":keys[k]
});
}
}
return columnsArray;
}
}
$(document).ready(function() {
var table = $('#example').DataTable({
"columns": getColumns(),
"data": data
});
});
Working example. Hope that helps.
dataTable require json data in return from ajax response having following keys
1. data
2. draw
3. recordsTotal
4. recordsFiltered
Use this:
var data = list.Select(u => u.GetType()
.GetProperties()
.Select(p => p.GetValue(u, null)));
example
public class User
{
public int userId { get; set; }
public string name { get; set; }
}
public class Programm
{
static void Main()
{
var list = new List<User>();
list.Add(new User
{
userId = 1,
name = "name 1",
});
list.Add(new User
{
userId = 2,
name = "name 2",
});
var data = list.Select(u => u.GetType()
.GetProperties()
.Select(p => p.GetValue(u, null)));
Console.WriteLine(new JavaScriptSerializer().Serialize(new
{
data = data
}));
}
}
result
{
"data" : [
["1", "name 1"],
["2", "name 2"]
]
}
I have the following C# model :
[ElasticType(Name = "myType")]
public class MyType
{
...
[ElasticProperty(Name = "ElasticId")]
[DataMember(Name = "ElasticId")]
public string ElasticId { get; set; }
...
[ElasticProperty(Name = "DateToBeUsed", Type = FieldType.Date, DateFormat = "date_hour_minute_second_millis")]
public string DateToBeUsed { get; set; }
...
}
The "date_hour_minute_second_millis" correspond to following format : yyyy-MM-dd’T'HH:mm:ss.SSS
(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-date-format.html)
The mapping ES is done with Nest using "map" method and correspond to that :
"mappings": {
"myType": {
"properties": {
...,
"ElasticId": {
"type": "string"
},
...,
"DateToBeUsed": {
"type": "date",
"format": "date_hour_minute_second_millis"
},
...
}
}
}
I insert an document inside this index:
"_source": {
...,
"ElasticId": "2",
...,
"DateToBeUsed": "2012-05-21T09:51:34.073",
...
}
My problem is when I want to retrieve this object through Nest.
The value of DateToBeUsed is always formatted with the following format : MM/dd/yyyy HH:mm:ss
(ex : 05/21/2012 09:51:34)
(Using sense, the value is well formatted.)
1°) Is this normal?
I need to retrieve the same date format than the one I gave to ES.
(And I think it should be normal to have the same format as described in the mapping)
2°) Is there a "clean" solution to resolve this problem?
(Re-formatting the date after having retrieved the document is not a "clean" solution...)
Thanks for the answers!
Bye.
I've tried to reproduce what you're seeing, using the following code, but the date value is being returned in the Get call as expected:
string indexName = "so-27927069";
// --- create index ---
client.CreateIndex(cid => cid.Index(indexName));
Console.WriteLine("created index");
// --- define map ---
client.Map<MyType>(m => m
.Index(indexName)
.Type("myType")
.MapFromAttributes());
Console.WriteLine("set mapping");
// ---- index -----
client.Index<MyType>(
new MyType
{
DateToBeUsed = new DateTime(2012, 5, 21, 9, 51, 34, 73)
.ToString("yyyy-MM-ddThh:mm:ss.fff"),
ElasticId = "2"
},
i => i
.Index(indexName)
.Type("myType")
.Id(2)
);
Console.WriteLine("doc indexed");
// ---- get -----
var doc = client.Get<MyType>(i => i
.Index(indexName)
.Type("myType")
.Id(2)
);
Console.WriteLine();
Console.WriteLine("doc.Source.DateToBeUsed: ");
Console.WriteLine(doc.Source.DateToBeUsed);
Console.WriteLine();
Console.WriteLine("doc.RequestInformation.ResponseRaw: ");
Console.WriteLine(Encoding.UTF8.GetString(doc.RequestInformation.ResponseRaw));
I'm seeing the following result as output:
created index
set mapping
doc indexed
doc.Source.DateToBeUsed:
2012-05-21T09:51:34.073
doc.RequestInformation.ResponseRaw:
{"_index":"so-27927069","_type":"myType","_id":"2","_version":1,"found":true,"_source":{
"ElasticId": "2",
"DateToBeUsed": "2012-05-21T09:51:34.073"
}}
(Watching the traffic via Fiddler, I'm seeing an exact match between the ResponseRaw value and the payload of the response to the Get request.)
I'm on Elasticsearch version 1.5.2 and NEST version 1.6.0. (Maybe the issue you were seeing was fixed sometime in the interim....)