JsonConvert.DeserializeAnonymousType definition syntax issue - c#

I have the following code:
var definition = new { result = "", accountinformation = new[] { "" , "" , "" } };
var accountInformationResult = JsonConvert.DeserializeAnonymousType(responseBody, definition);
The account information structure comes back from an endpoint as an array with each element being another array containing 3 strings. So the embedded array is not in a key value pair format. With the above definition accountinformation returns null. What should the syntax be for this structure?
For reference this is what is going on in the php endpoint.
$account_information[] = array( $billing_company, $customer_account_number, $customer_account_manager );
This first line is in a loop. Hence the multi-dimensional array.
echo json_encode(array('result'=>$result, 'account_information'=>$account_information));
I know I could use dynamic but why the extra effort?

I assume your json will look something like this:
{
"result": "the result",
"account_information": [
["company1", "account_number1", "account_manager1"],
["company2", "account_number2", "account_manager2"]
]
}
In that case you should be able to deserialize with the following definition (note the underscore in account_information:
var definition = new { result = "", account_information = new List<string[]>() };
In json you are allowed to add extra properties as you please while your data model changes. So if you define a data model that does not include one of these properties, the property will simple be ignored. In your case the definition does not have a property called account_information (exactly), so this part of the json is ignored while deserializing.
EDIT:
If it's going to be an anonymous abject anyway, you may also consider parsing into a JObject:
var obj = JObject.Parse(responseBody);
string firstCompany = obj["account_information"][0][0];
string secondCompany = obj["account_information"][1][0];

Related

Attempting simple proof of concept of microsoft / RulesEngine but getting JsonSerializationException

I'm assuming I've made a stupid mistake here, but wondering if someone could assist?
I am trying out the following library:
Install-Package RulesEngine -Version 3.2.0
My rules.json is as follows:
[
{
"WorkflowName": "DeliverToMatchingSuburb",
"Rules": [
{
"RuleName": "MatchingSuburb",
"Expression": "customer.PostCode == location.PostCode"
}
]
}
]
My code:
string[] readText = File.ReadAllLines("rules.json");
Customer c = new Customer();
Pharmacy p = new Pharmacy();
var pharmacies = p.GetLocations();
var customers = c.GenerateCustomers();
var re = new RulesEngine.RulesEngine(readText, null);
My attempt to pass 'readText' into the RulesEngine however gives me the following exception?
Newtonsoft.Json.JsonSerializationException: 'Unexpected end when reading JSON. Path '', line 1, position 1.'
The exception occurs at this line: var re = new RulesEngine.RulesEngine(readText, null);
I have checked that the JSON is valid by using an online JSON
validator.
I've also tried adding curly braces at the top and
bottom.
I've even tried copy/pasting the example rules JSON from the
documentation here
https://github.com/microsoft/RulesEngine#how-to-use-it (knowing
it won't work but should at least pass the step of creating the
RulesEngine) but that too fails with the same error.
The expectation for the RulesEngine(string[], ILogger, ReSettings) constructor is that each element of the string array is a complete JSON object. In your case, you've provided just a single line per array element.
Given that your text file already contains a collection of rules, you should deserialize it yourself, and pass the deserialized collection into the constructor accepting a WorkflowRules[]:
string json = File.ReadAllText("rules.json");
var rules = JsonConvert.DeserializeObject<WorkflowRules[]>(json);
var engine = new RulesEngine.RulesEngine(rules);

Newtonsoft Get sub key from json without indexer syntax

I got a json with some nested object, for example:
{
"OrganizationData": {
"Org1": {
"Name": "Rega And Dodli",
"EmployessNum": "100000000"
},
"Org2": {
"Name": "Sami And Soso",
"EmployessNum": "2"
}
}
}
I want to get for example the value for the "Name" of "Org1".
I know I can do something like this:
var rss = JObject.Parse(mystring);
var value = rss["OrganizationData"]["Org1"]["Name"];
My question is if it's possible to replace the multiple indexers part (["OrganizationData"]["Org1"]["Name"]) with a single indexer (or something else which is not an indexer) with a single string which is composed of all 3 keys and still get the same value?
For example something like:
var rss = JObject.Parse(mystring);
var value = rss["OrganizationData:Org1:Name"];
I remember there's something with ":" but this one I tried in the example above did not work.
You can use the JObject.SelectToken method, using period (.) as the property path delimiter. For example:
var value = rss.SelectToken("OrganizationData.Org1.Name");

Replace Json properties with NewtonSoft

No idea where to begin with this, so I don't have any sample code.
I need to change the name of a property in a json document.
var json = (#"{""id"":""12"",
""title"":""My Title"",
""Chunks"":[
{
""id"":""137"",
""title"":""Title"",
""description"":""null"",
""selections"":[
{
""id"":""169"",
""title"":""Choice"",
""sort_order"":""null"",
""questions"":[
]
}
]
}
]
}
}
}");
I need to change the "id" that's got the value of 12 to "document_id" and leave the other ids alone. Are there any C# libraries like NewtonSoft that allow you to change the property rather than the property value. Seems like a common scenario but I haven't seen anything close to what I'm trying to do. I suppose I could convert the json to a string and do a replace, but that doesn't seem very elegant.
An approach using Newtonsoft.Json.Linq.JObject would look something like:
var obj = JObject.Parse(json);
obj["document_id"] = obj["id"]; // create new property called "document_id"
obj.Remove("id"); // remove the "id" property
Console.WriteLine(obj);
Also note that your JSON is not valid. It has two extra } at the end.
Assuming you would want to replace all the keys when there could be more than one node with key as "id" and value "12", you could use Linq to identify Tokens with Key "Id" and Value "12" and then use Add/Remove methods for creating a new node with different name.
For example,
JToken node = JToken.Parse(json);
var jObjectsWithTitle = node
.SelectTokens("$..*")
.OfType<JObject>()
.Where(x => x.Property("id") != null && Convert.ToInt32(x.Property("id").Value) == 12);
foreach(var item in jObjectsWithTitle)
{
item.TryGetValue("id",out var currentValue);
item.Add("document_id",currentValue);
item.Remove("id");
}

Newtonsoft.Json.Linq.JArray.Parse(string)' has some invalid arguments

I am trying to extract data from D2L for the dropbox submissions using API's I have a link which returns a Json Array as per told on the documentation and from this Array I just need the Id feild nothing else.
I have tried to convert this Array into dynamic Object but that didn't help.
Here is my code.
var client = new RestClient("https://" + LMS_URL);
var authenticator = new ValenceAuthenticator(userContext);
string Link = "/d2l/api/le/1.12/UnitID/dropbox/folders/UniID/submissions/";
var request = new RestRequest(string.Format(Link));
request.Method = Method.GET;
authenticator.Authenticate(client, request);
var response = client.Execute(request);
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(response.Content);
Response.Write(jsonString);
//var splashInfo = JsonConvert.DeserializeObject<ObjectD>(response.Content);
dynamic jsonResponse = JsonConvert.DeserializeObject(response.Content);
var parsedObject = jsonResponse.Parse(jsonResponse);
string json = jsonResponse;
var popupJson = parsedObject["id"].ToString();
What my goal is that grab the list of ID's from this response and loop through them, these ID's are the key for my next API route.
Here is a glance at what I get from the response:
[
{
"Id": 2021,
"CategoryId": null,
"Name": "Graded Assignment: Part 1",
"CustomInstructions": {
"Text": "Directions:\r\nCOMPLETE the following TestOut Activities\r\n\r\n1.2.10 Practice Questions\r\n1.3.8 Practice Questions\r\n\r\nGo to TestOut to complete the Assignment."
//Other properties omitted
}
//Other properties omitted
}
]
The outermost container in the JSON returned is an array, so you need to deserialize to a collection type as specified in the Newtonsoft's Serialization Guide: IEnumerable, Lists, and Arrays.
Since you only care about the Id property of the object(s) in the array, you can use JsonConvert.DeserializeAnonymousType to deserialize just the interesting value(s):
var ids = JsonConvert.DeserializeAnonymousType(response.Content, new [] { new { Id = default(long) } })
.Select(o => o.Id)
.ToList();
And if you are certain the outermost array will contain exactly one item, you can do:
var id = JsonConvert.DeserializeAnonymousType(response.Content, new [] { new { Id = default(long) } })
.Select(o => o.Id)
.Single();
Alternatively, if you think you will later need to deserialize additional properties, you could make an explicit data model as follows:
public class ObjectId
{
public long Id { get; set; }
}
And do:
var ids = JsonConvert.DeserializeObject<List<ObjectId>>(response.Content)
.Select(o => o.Id)
.ToList();
Notes:
You will need to determine from the API documentation whether long or int is more appropriate for the Id value.
As a general rule I recommend not parsing to dynamic because you lose compile-time checking for correctness. When dealing with completely free-form JSON, parsing to JToken may be a better solution -- but your JSON appears to have a fixed schema, so neither is necessary.
Demo fiddle here.

How to use Json.Net to deserialize json that starts with a property name of a number?

I am trying to deserialize some JSON data from an API endpoint, and the data is enclosed in a {8: myData}. I cannot figure out how to deserialize it with the first property being named a number.
Example JSON:
{
8:
[
data,
data2,
data3,
data4
]
}
My deserializer line fails since the first property name of the JSON data is an 8:
IEnumerable<ApiCombatOverallRank> result = JsonConvert.DeserializeObject<IEnumerable<ApiCombatOverallRank>>(resultsString);
I can create an anonymous type like this:
var anonType = new { data = new List<ApiCombatOverallRank>() };
IEnumerable<ApiCombatOverallRank> result = JsonConvert.DeserializeAnonymousType(resultsString, anonType).data;
However, it will not deserialize as the property name in the JSON is 8 not data. C# will not allow me to create an anonymous object like:
var anonType = new { 8 = new List<ApiCombatOverallRank>() };
Similarly, I am unable to add an annotation to an anonomyous object like:
var anonType = new {[JsonProperty(PropertyName = "8")] data = new List<ApiCombatOverallRank>() };
How can I deserialize this JSON and get past the first JSON object property of 8?
Your json is parsebar as (after i made strings from your "data's" ):
var result = JsonConvert
.DeserializeObject<Dictionary<int, IEnumerable<string>>>(resultsString);
so i think, your real json you could parse as :
var result = JsonConvert
.DeserializeObject<Dictionary<int, IEnumerable<ApiCombatOverallRank>>>(resultsString);
and your first kson object your could access as:
result[8].First();

Categories

Resources