Why are my inner object property names not camel cased? - c#

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.

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"
}
]
}
]
}

How to serialize sql data without the column names?

I am Serializing data from SQL database to JSON, how can I serialize just the values without the string name OR a function to trim the serialized JSON before Deserializing.
I read about ScriptIgnoreAttribute but didn't see how to relate it with what I want to do
Original JSON
​[
{
"CODE": "AF",
"TOTALVALUE": "$23,554,857.27"
},
{
"CODE": "AS",
"TOTALVALUE": "$38,379,964.65"
},
{
"CODE": "SG",
"TOTALVALUE": "$24,134,283.47"
}
]
Desired JSON
​[
{
"AF": "$23,554,857.27"
},
{
"AS": "$38,379,964.65"
},
{
"SG": "$24,134,283.47"
}
]
SQL View structure
My SQL query to return the data
SELECT [CODE],[TOTALVALUE] FROM [dbo].[vw_BuyersByCountryValue]
enter code here
Code for Serializing in ASP.NET
[WebMethod]
public void GetBuyersByCountryValue()
{
using (PMMCEntities ctx = new PMMCEntities())
{
ctx.Configuration.ProxyCreationEnabled = false;
var qry = ctx.vw_BuyersByCountryValue.ToList();
var js = new JavaScriptSerializer();
string strResponse = js.Serialize(qry);
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-length", strResponse.Length.ToString(CultureInfo.InvariantCulture));
Context.Response.Flush();
Context.Response.Write(strResponse);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
It is very simple
// data from the query
// SELECT CODE, TOTALVALUE FROM vw_BuyersByCountryValue
var sqldata = new []
{
new { Code = "AF", TotalValue = "$23,554,857.27" },
new { Code = "AS", TotalValue = "$38,379,964.65" },
new { Code = "SG", TotalValue = "$24,134,283.47" },
};
var mappeddata = sqldata.Select( r =>
{
var dict = new Dictionary<string,string>();
dict[r.Code] = r.TotalValue;
return dict;
});
var json = JsonConvert.SerializeObject(mappeddata,Formatting.Indented);
content of json
[
{
"AF": "$23,554,857.27"
},
{
"AS": "$38,379,964.65"
},
{
"SG": "$24,134,283.47"
}
]
.net fiddle sample
You can even populate it as
{
"AF": "$23,554,857.27",
"AS": "$38,379,964.65",
"SG": "$24,134,283.47"
}
with
var sqldata = new []
{
new { Code = "AF", TotalValue = "$23,554,857.27" },
new { Code = "AS", TotalValue = "$38,379,964.65" },
new { Code = "SG", TotalValue = "$24,134,283.47" },
};
var mappeddata = sqldata.ToDictionary(r => r.Code, r => r.TotalValue);
var json = JsonConvert.SerializeObject(mappeddata,Formatting.Indented);
.net fiddle sample
Update
[WebMethod]
public void GetBuyersByCountryValue()
{
using (PMMCEntities ctx = new PMMCEntities())
{
ctx.Configuration.ProxyCreationEnabled = false;
var qry = ctx.vw_BuyersByCountryValue.ToList();
var mapped = qry.Select r =>
{
var dict = new Dictionary<string,string>();
dict[r.CODE] = r.TOTALVALUE;
return dict;
});
string strResponse = Newtonsoft.Json.JsonConvert.SerializeObject(mapped);
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-length", strResponse.Length.ToString(CultureInfo.InvariantCulture));
Context.Response.Flush();
Context.Response.Write(strResponse);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
You need the NuGet package Newtonsoft.Json

Onesignal c# web_buttons

I am trying to send a notification from my backend with the following code:
var obj = new
{
app_id = new Guid(ConfigurationManager.AppSettings["oneSignalAppid"]),
contents = new { en = "English Message"},
headings = new { en = "English heading" },
chrome_web_image = https://pixabay.com/static/img/no_hotlinking.png",
web_buttons = #"[
{
'id': 'like-button',
'text': 'Like',
'icon': 'http://i.imgur.com/N8SN8ZS.png',
'url': 'https://yoursite.com'},
{
'id': 'read-more-button',
'text': 'Read more',
'icon': 'http://i.imgur.com/MIxJp1L.png',
'url': 'https://yoursite.com'
}]",
included_segments = new string[] { "All" }
};
either i get a 400 response or i get my notification without the buttons.
How do i set the web_buttons properly?
the solution is to serialize the array object using anonymous array of anonymous types:
web_buttons = new[] {
new {id="id-1", text= buttonText, url="http://yourDomain.com" },
}
...

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" }
}
}
);

Create nested json with 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.

Categories

Resources