I am new to C# and I am trying to create an object in a similar way that we create them in js:
var obj = {
'method' : 'connect',
'data' : {
'somekey' : 'data',
'somekey2' : 'data',
'somekey3' : 'data',
'somekey4' : 'data'
}};
Eventually this will be converted into JSON. So far I have tried using a dictionary like this:
connect.Method = "connect";
connect.Data = new Dictionary<string, object>();
connect.Data.Add("data", new Dictionary<string, object>()
{
{ "somekey", "data" },
{ "somekey2", "data" },
{ "somekey3", "data" },
{ "somekey4", "data" }
}
);
but doing that in the json output it looks like:
{
"Method":"connect",
"Data":{
"data":{
"somekey":"data",
"somekey2":"data",
"somekey3":"data",
"somekey4":"data"}
}
}
Which is problematic because the M in method shouldn't be capitalized (its that way because how I defined the class I am sure I can fix this one myself.
The main issue is the extra "Data" that is getting added into the JSON.
Does anyone have any ideas of a better way to do this, I am trying to avoid just using huge strings to convert into JSON.
In your C# code you create 2 dictionaries inside each other. That's why you get the extra levels in the structure.
You could eliminate one level by doing this
connect.Method = "connect";
connect.Data = new Dictionary<string, object>
{
{ "somekey", "data" },
{ "somekey2", "data" },
{ "somekey3", "data" },
{ "somekey4", "data" }
};
As for having lower case variable names, you can add the JsonProperty attribute to the fields. Here are the docs: https://www.newtonsoft.com/json/help/html/JsonPropertyName.htm
Related
Is there any way to use Filters in C# and translate this mongo query?
{'EmailData.Attachments.Files': {$all: [{Name: 'a.txt'},{Name: 'b.txt'},{Name:'c.txt'}], $size: 3}}
my data model is like:
{
"_id": ObjectId("5f0a9c07b001406068c073c1"),
"EmailData" : [
{
"Attachments" : {
"Files" : [
{
"Name" : "a.txt"
},
{
"Name" : "b.txt"
},
{
"Name" : "c.txt"
}
]
}
}
]
}
I have something like this in my mind:
var Filter =
Builders<EmailEntity>.Filter.All(s => s.EmailData????);
or something like:
var Filter =
Builders<EmailEntity>.Filter.ElemMatch(s => s.EmailData???)
I was wondering is there any way in the above filter to use All inside ElemMatch?
The difficulty here is that EmailData.Attachments.Files is an array within another array so C# compiler will get lost when you try to use Expression Trees.
Thankfully there's another approach when you need to define a field using MongoDB .NET driver. You can take advantage of StringFieldDefinition<T> class.
Try:
var files = new[] { new FileData(){ Name = "a.txt"}, new FileData() { Name = "b.txt" }, new FileData() { Name = "c.txt" } };
FieldDefinition<EmailEntity> fieldDef = new StringFieldDefinition<EmailEntity>("EmailData.Attachments.Files");
var filter = Builders<EmailEntity>.Filter.And(
Builders<EmailEntity>.Filter.All(fieldDef, files),
Builders<EmailEntity>.Filter.Size(fieldDef, 3));
var result= collection.Find(filter).ToList();
I have tried numerous times and also tried to consult the documentation provided by Newtonsoft website but there doesn't seem to be any answer regarding my issue. I have also searched Google for no avail, wasted around 4 hours with no answer but just to continue without it.
My issue is that can't add a JObject into a JArray with a Key. I understand it seems rather simple task but whatever I tried ended up in an Exception being thrown out.
I am trying to write a simple file with the following layout:
{
"items" : [
"item 1" : { },
"item 2" : { },
]
}
// the actual layout that I have is
{
"items" : [
{ },
{ },
]
}
I can successfully add the first items key for JArray through jobj["items"] = jarray but I cant seem to use the same technique with JArray. I need to add items in JArray through JArray.Add() and it doesn't let me provide a key. I'm actually lost on this. Can someone please explain as how can I achieve the above layout? Thank you.
As #dbc mentioned, the format which you require is not valid. The nearest valid format you could achieve is as following.
{
"items":
{
"item 1":{},
"item 2":{}
}
}
You could achieve it using a Data structure containing a Dictionary. For Example
var data = new DataStructure{
items = new Dictionary<string,Item>()
{
["Item 1"] = new Item{},
["Item 2"] = new Item{}
}};
Where DataStructure and Item is defined as
public class DataStructure
{
public Dictionary<string,Item> items{get;set;}
}
public class Item
{
}
If you do not want to create concrete class, you can achieve the same using anonymous types
var data = new {items = new Dictionary<string,Item>()
{
["Item 1"] = new Item{},
["Item 2"] = new Item{}
}};
or, if you want to avoid creation of Item Class as well
var data = new {items = new Dictionary<string,object>()
{
["Item 1"] = new {},
["Item 2"] = new {}
}};
Output
{
"items": {
"Item 1": {},
"Item 2": {}
}
}
As it has been suggested in the comment, my desired layout is not a right one. As it appears json needs an anonymous object within the array to hold a keyed object.
So the layout should be:
{
"items" : [
{
"item1" : { }
},
.......
]
}
Recently, I have been dabbling in reading json data into my C# code with the intent of storing property data in the json file to be loaded at run time. For example, I'd like to make a json file for each datagrid and have each column represented as a unique as a section in the json file; something like this:
[
{
"colWidth": 1,
"rowHeight": 10,
"moreStuff": 20
},
{
"ColWidth": 2,
"rowHeight": 100,
"SecondBAID": 200
},
{
"ColWidth": 3,
"rowHeight": 1000,
"moreStuff": 2000
},
{
"ColWidth": 4,
"rowHeight": 10000,
"moreStuff": 20000,
"someArray: [true, 5, "Column notes"]
},
{
"ColWidth": 5,
"rowHeight": 100000,
"moreStuff": 200000,
"evenMoreStuff":300000
}
]
The code I am currently using to read this file and assign the data is as follows:
public static void LoadJson()
{
string json;
using (StreamReader r = new StreamReader(#"test.json"))
{
json = r.ReadToEnd();
}
dynamic array = JsonConvert.DeserializeObject(json);
var list = new List<MyClass>();
foreach (var section in array)
{
var si = new MyClass();
if (section.Whatever!= null)
{
si.Test1 = section.Whatever;
}
if (section.Whatever2!= null)
{
si.Test2 = section.Whatever2;
}
if (section.Whatever3!= null)
{
si.Test3 = section.Whatever3;
}
if (section.Whatever4!= null)
{
si.Test4 = section.Whatever4;
}
list.Add(si);
}
}
I have a few questions regarding this though...
1) Is there an easier way to filter out null values? Sometimes I want the property of a column to be the default value, and I'd rather not nest dozens of if statements if possible. Is there a way to basically say "If this property doesn't exist in the json section, just ignore it"
Presently I am just iterating through all of the possible properties, doing a simple get/set in the MyClass, and storing the variables (For this example, I use "whatevers" so I don't post hundreds of lines of code; the whatevers represent legitimate fields in the json file.
2) I am currently adding each section of the json file to a dynamic array. How can I achieve this when I want to add an array of properties to the dynamic array? I'd like to change the C# code such that if I have a nested array, it will be added to some sort of multi level list. What is the best way to do this?
I'm using this (Is it possible to have nested array json?) as a reference to nest arrays in the json.
Any advise would be awesome!
I have a C# class which contains a property of Dictionary
I have a web-page which contains a list of items i need to cast into this dictionary.
My web-site will send the list up to my C# MVC application as JSON and then JsonConvert.Deserialise the JSON into my Dictionary object.
JsonConvert.Deserialise is expecting JSON in the following format:
"MyVariableName":{
"Item 1":true,
"Item 2":true
}
I need to know how i can construct this object in JavaScript.
So far, i have tried this without luck:
var items = [];
var v = $('#Items :input');
$.each(v, function(key, val) {
items.push({
key: val.value,
value: val.checked
});
});
JSON.stringify(v, null, 2);
But this returns a json converted value of:
"MyVariableName": [
{
"key": "Item 1",
"value": true
},
{
"key": "Item 2",
"value": true
}]
Which in turn does not de-serialize to my dictionary.
Thanks
Don't make an array; make an object:
var items = {};
$('#Items :input').each(function(i, val) {
items[val.value] = val.checked;
});
You have to use javascript serialization
One more thing you have different value int key, value pair like string and Boolean type, so you have to use Dictionary type.
And JavaScriptSerializerobject you will get System.Web.Script.Serialization name space of System.Web.Extensions.dll, v4.0.30319 assembly.
var jSerializer = new JavaScriptSerializer();
var newList= jSerializer.Deserialize<Dictionary<string,object>>(newData);
I'm trying to generate JSON using C# and DataContractJsonSerializer in .Net 3.5. The problem is that I can't figure out how to build the structure correct for the result I need.
I've tried to reproduce PHP's associative arrays using both hashtables, list objects and arraylists but can't figure out how to generate my result in the best way using DataContractJsonSerializer without having to create my own recursive loop for building JSON.
The closest approach is using the a Dictionary < string, Dictionary < string, string>> aproach but the result is too big as I can't "name" the keys.
This is what I get:
[
{
"Key":"status",
"Value":[
{
"Key":"value",
"Value":"ok"
}
]
},
{
"Key":"1",
"Value":[
{
"Key":"name",
"Value":"Result1"
},
{
"Key":"details",
"Value":"Result 1 details"
}
]
},
{
"Key":"2",
"Value":[
{
"Key":"name",
"Value":"Result2"
},
{
"Key":"details",
"Value":"Result 2 details"
}
]
},
{
"Key":"caller",
"Value":[
{
"Key":"value",
"Value":"1135345"
}
]
}
]
This is what I want:
{
"status":"ok",
"response":[
{
"id":1,
"name":"Result1"
"details":"Result 1 details"
},
{
"id":2,
"name":"Result2"
"details":"Result 2 details"
},
{
"id":3,
"name":"Result3"
"details":"Result 3 details"
],
"caller":"1135345"
}
Does anybody have a clue how I can generate this piece of JSON using C# without having to load the entire Json.NET framework? I need this to be generated as fast as possible as this project aims to become an site search engine.
You should look at using the JavaScriptSerializer. It's part of the .NET framework (distributed in System.Web.Extensions). To get the result you want you can do this:
var results = new[]
{
new{id=1,name="Result 1"},
new{id=2,name="Result 2"},
new{id=3,name="Result 3"}
};
var js = new JavaScriptSerializer();
var result = js.Serialize(new
{
status = "ok",
response = results,
caller = 1135345
});
You can either use anonymous classes, or any existing ones. Works perfectly fine :)
The return value of this call would be:
{"status":"ok","response":[{"id":1,"name":"Result 1"},{"id":2,"name":"Result 2"},{"id":3,"name":"Result 3"}],"caller":1135345}
Using the JavaScriptSerializer rather than DataContractJsonSerializer on a Dictionary will remove the Key/Value json attributes and make them into a "keyed" array.
http://msdn.microsoft.com/en-us/library/bb412168.aspx
Have you attributed your classes with the [DataContract] and [DataMember] decorators?
http://msdn.microsoft.com/en-us/library/bb412179.aspx