Create nested json with c# - c#

I am able to create a flat serialized JSON string pretty easily with c#
My issue is I want to create a nested string like this below
[ {
title: "Yes",
id : "1",
menu: [ {
title: "Maybe",
id : "3",
alert : "No",
menu: [ {
title: "Maybe Not",
id : "8",
alert : "No",
menu: []
} ]
} ]
},
{
title: "No",
id : "2",
menu: []
}]
Any help would be great

Are you using MVC 3? - Do something like:
return Json(myObectWithListProperties, JsonRequestBehavior.AllowGet);
I use this to return complex C# objects that match the structure of the JavaScript objects I want.
e.g.:
var bob = new {
name = "test",
orders = new [] {
new { itemNo = 1, description = "desc" },
new { itemNo = 2, description = "desc2" }
}
};
return Json(bob, JsonRequestBehavior.AllowGet);
gives:
{
"name": "test",
"orders": [
{
"itemNo": 1,
"description": "desc"
},
{
"itemNo": 2,
"description": "desc2"
}
]
}
EDIT: A bit more nesting for fun:
var bob = new {
name = "test",
orders = new [] {
new { itemNo = 1, description = "desc" },
new { itemNo = 2, description = "desc2" }
},
test = new {
a = new {
b = new {
something = "testing",
someOtherThing = new {
aProperty = "1",
another = "2",
theThird = new {
bob = "quiteDeepNesting"
}
}
}
}
}
};
return Json(bob, JsonRequestBehavior.AllowGet);
gives:
{
"name": "test",
"orders": [
{
"itemNo": 1,
"description": "desc"
},
{
"itemNo": 2,
"description": "desc2"
}
],
"test": {
"a": {
"b": {
"something": "testing",
"someOtherThing": {
"aProperty": "1",
"another": "2",
"theThird": {
"bob": "quiteDeepNesting"
}
}
}
}
}
}

Try using
using System.Web.Script.Serialization;
//Assumed code to connect to a DB and get data out using a Reader goes here
Object data = new {
a = reader.GetString(field1),
b = reader.GetString(field2),
c = reader.GetString(field3)
};
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string json = javaScriptSerializer.Serialize(data);
This is built-in and saves you the work of serializing to JSON yourself!
This example assumes you are getting data from a database using some sort of reader, and it then constructs the object you want to serialize using an anonymous class. Your anonymous class can be as simple or complex as you need it to be and the JavaScriptSerializer will handle transforming it to JSON. This approach is also useful because you can easily control the JSON property names it will create in the JSON.

using System.Web.Script.Serialization;
var strNJson = new
{
to = "hello",
notification = new
{
title = "textTitle",
body = "bodyText"
}
};
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string json = javaScriptSerializer.Serialize(strNJson);
{ "to":"hello",
"notification": {
"title":"titleText",
"body":"bodyText"
}
}

You can make use of the ExpandoObject under the System.Dynamic namespace.
Here is a small snippet for achieving your solution:
dynamic parameters = new dynamic[2];
parameters[0] = new ExpandoObject();
parameters[0].title = "Yes";
parameters[0].id = "1";
parameters[0].menu = new dynamic[1];
parameters[0].menu[0] = new ExpandoObject();
parameters[0].menu[0].title = "Maybe";
parameters[0].menu[0].id = "3";
parameters[0].menu[0].alert = "No";
parameters[0].menu[0].menu = new dynamic[1];
parameters[0].menu[0].menu[0] = new ExpandoObject();
parameters[0].menu[0].menu[0].title = "Maybe Not";
parameters[0].menu[0].menu[0].id = "8";
parameters[0].menu[0].menu[0].alert = "No";
parameters[0].menu[0].menu[0].menu = new dynamic[0];
parameters[1] = new ExpandoObject();
parameters[1].title = "No";
parameters[1].id = "2";
parameters[1].menu = new dynamic[0];
string json = JsonConvert.SerializeObject(parameters, Formatting.Indented);
Console.WriteLine(json);
Here is the work in fiddle
Note: There are other ways to achieve this, but I have been using this approach.

Related

How can I easily create readable JSON objects in C# .Net Core similar to JavaScript

In JavaScript I can easily create an object and assign variables with some very basic notation such as:
const Object = JSON.parse('
{
"something": outsideVariable,
"someArray": [
"hey",
"there"
]
}
');
Is there a simple way to do this with C# that is clean and easy to assign variables too? I experimented a bit with the JsonObject but the code for that looks needlessly messy, for example:
JsonObject jsonPayload = new JsonObject
{
["documentId"] = documentID,
["testMode"] = true,
["signers"] = new JsonArray
{
new JsonObject
{
["label"] = "John Smith",
["contactMethod"] = new JsonArray
{
new JsonObject
{
["type"] = "link"
}
}
}
}
};
I also tried using the literal symbol (#) with a string, but it ends up injecting carriage returns and linefeeds, and inserting variables winds of being a great deal of concatination.
IMHO , the most close you want is this
var jsonPayload = new
{
documentId = 1,
testMode = true,
signers = new object[]
{
new {
label="John Smith",
contactMethod= new object[]
{
new {
type="link"
}
}
}
}
};
and code
var json= System.Text.Json.JsonSerializer
.Serialize(jsonPayload,new JsonSerializerOptions { WriteIndented = true });
//or if you need
var jsonParsed= JsonDocument.Parse(json);
result
{
"documentId": 1,
"testMode": true,
"signers": [
{
"label": "John Smith",
"contactMethod": [
{
"type": "link"
}
]
}
]
}

Why are my inner object property names not camel cased?

I'm struggling with a serialization problem.
I have a column in a SQL table that contains a pascal cased JSON fragment:
{
"HistoryOpertions": [
{
"OperationTitle": "Titre Op",
"OperationDetails": "Details Op"
},
{
"OperationTitle": "2",
"OperationDetails": "Op 2"
},
{
"OperationTitle": "by Ol",
"OperationDetails": "Test",
"OperateurName": "Olivier Matrot",
"TimeStamp": 637100138608377997
}
],
"TimestampLastModification": "2019-11-29T11:09:16.1621275Z",
"AlertInstructions": [
{
"InstructionId": 1,
"OperateurName": null,
"CheckPoint": false,
"TimeStamp": null
}
],
"AlertTitle": "Alerte safe protect",
"LiftingDoubtId": 2,
"SupportId": 3
}
I have the following code that parse this fragment, apply some modifications crates a new object and serialize it back to a string. This time I want property names to be camel cased:
var json = JObject.Parse(existingAlertDetailEntity.SafeProtectCustomInfo ?? "{}");
JArray alertInstructions = json["AlertInstructions"] as JArray;
foreach (var instruction in alertInstructions)
{
if (instruction[nameof(AlertInstruction.InstructionId)].ToObject<int>() == model.InstructionId)
{
bUpdated = true;
instruction[nameof(AlertInstruction.TimeStamp)] = model.Status ? DateTime.UtcNow.Ticks : (long?)null;
instruction[nameof(AlertInstruction.OperateurName)] = model.Status ? user.DisplayName : null;
instruction[nameof(AlertInstruction.CheckPoint)] = model.Status;
break;
}
}
var jsonSerializer = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore,ContractResolver = new CamelCasePropertyNamesContractResolver() };
string jsonToBeReturned = JsonConvert.SerializeObject(
new {
model.AlertId,
AlertInstructions = JArray.FromObject(
json["AlertInstructions"],
JsonSerializer.Create(new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
})),
}, jsonSerializer);
And here is the result:
{
"alertId":1295041,
"alertInstructions":[
{
"InstructionId":1,
"TimeStamp":637111473877506411,
"OperateurName":"Olivier Matrot",
"CheckPoint":true
},
{
"InstructionId":2,
"TimeStamp":637112167087671938,
"OperateurName":"Olivier Matrot",
"CheckPoint":true
}
]
}
We can see that the alertInstructions array still contains Pascal Cased property names.
You could deserialize your JSON using an ExpandoObject, modify that and serialize it to a string.
var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore,ContractResolver = new CamelCasePropertyNamesContractResolver() };
dynamic json = JsonConvert.DeserializeObject<ExpandoObject>(JSON);
// modify your structure here...
json.AlertInstructions[0].TimeStamp = 1234;
var jsonToBeReturned = JsonConvert.SerializeObject(new {
AlertId = 42,
AlertInstructions = json.AlertInstructions
}, Formatting.Indented, settings);
See also the fiddle for an example.

How create the filters in Function Score Query with .NET NEST Client

In Elasticsearch Document describe about Function Score Query show code as below
GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"functions": [
{
"filter": { "match": { "test": "bar" } },
"random_score": {},
"weight": 23
},
{
"filter": { "match": { "test": "cat" } },
"weight": 42
}
],
"max_boost": 42,
"score_mode": "max",
"boost_mode": "multiply",
"min_score" : 42
}
}
}
I write this query to object initializer syntax
var searchRequest = new SearchRequest<ProductType>
{
Query = new FunctionScoreQuery()
{
Query = new MatchAllQuery {},
Boost = 5,
Functions = new List<IScoreFunction>
{
Filters...?
},
MaxBoost = 42,
ScoreMode = FunctionScoreMode.Max,
BoostMode = FunctionBoostMode.Max,
MinScore = 42
}
};
How to build filters in Functions?
The IScoreFunction interface allow only ExponentialDecayFunction, GaussDateDecayFunction, LinearGeoDecayFunction, FieldValueFactorFunction, RandomScoreFunction, WeightFunction, ScriptScoreFunction
Functions is a collection of IScoreFunction. In the example JSON, the first function is a random score function, and the second, a weight function. The linked Query DSL example has examples of the different functions, and here's an example to match the JSON above
var client = new ElasticClient();
var searchRequest = new SearchRequest<ProductType>
{
Query = new FunctionScoreQuery()
{
Query = new MatchAllQuery { },
Boost = 5,
Functions = new List<IScoreFunction>
{
new RandomScoreFunction
{
Filter = new MatchQuery
{
Field = "test",
Query = "bar"
},
Weight = 23
},
new WeightFunction
{
Filter = new MatchQuery
{
Field = "test",
Query = "cat"
},
Weight = 42
}
},
MaxBoost = 42,
ScoreMode = FunctionScoreMode.Max,
BoostMode = FunctionBoostMode.Multiply,
MinScore = 42
}
};
var searchResponse = client.Search<ProductType>(searchRequest);

Creating JSON out of string

I want to get JSON similar to this
{
"Name": "xxxxx",
"ApplicationId": "xxxxx",
"Features": [
{
"Name": "xxxxx",
"Code": "xxxxx",
}
]
}
and my code is so far is
var json = JsonConvert.SerializeObject(
new {
Name = name ,
ApplicationId = applicationID ,
Features = (new[]{feature_name , feature_code})
}, Formatting.None);
I can not figure out the feature part, it won't get created as in the example.
I read so many post, but did not find anything about inner objects.
You didn't give the features appropriate names, hence then variable names are used.
Use this instead:
new[] { new { Name = feature_name, Code = feature_code } }
Also, you have to supply a list of features, for example using LINQ.
features.Select(f => new { Name = f.feature_name, Code = f.feature_code })
Another way of doing this can be like:
var createJson = new {
Name = "xxxxx",
ApplicationId = "xxxxx",
Features = new[] {
new { Name = "xxxxx", Code = "xxxxx" },
new { Name = "xxxxx", Code = "xxxxx" }
}
};
var json = JsonConvert.SerializeObject(createjson, Formatting.Indented);

JSON data in PUT request in C#

I am trying to make a PUT request with a C# client, this request has JSON data in it.
I use this, which I got from here: Passing values to a PUT JSON Request in C#
var serializer = new JavaScriptSerializer();
string json = serializer.Serialize(new
{
reg_FirstName = "Bob",
reg_LastName = "The Guy"
});
Ofcourse, the Json string looks like this:
{
"reg_FirstName":"Bob",
"reg_LastName":"The Guy"
}
But how would I go around creating a JSON string like this:
{
"main": {
"reg_FirstName": "Bob",
"reg_LastName": "The Guy"
},
"others": [
{
"reg_FirstName": "Robert",
"reg_LastName": "The Guy"
},
{
"reg_FirstName": "Rob",
"reg_LastName": "The Guy"
}
]
}
You can use the same way - dynamic objects, so in your case it would look like this:
var serializer = new JavaScriptSerializer();
string json =
serializer.Serialize(
new {
main = new
{
reg_FirstName = "Bob",
reg_LastName = "The Guy"
},
others = new[]
{
new { reg_FirstName = "Bob", reg_LastName = "The Guy" },
new { reg_FirstName = "Bob", reg_LastName = "The Guy" }
}
}
);

Categories

Resources