Deserialize JSON string with Date Headings - C# - No JSON.Net - c#

I need to deserialize and/or export to csv a JSON string being sent back to me. The problem is that the JSON string is formatted in a way that results dates being used as the headers.
See example below:
{"2017-01-09":{"chats":129,"missed_chats":0},
"2017-01-10":{"chats":347,"missed_chats":0},
"2017-01-11":{"chats":194,"missed_chats":0},
"2017-01-12":{"chats":229,"missed_chats":0}}
Because of this, I do not believe I can make a class to hold them as each date would need its own class to match the heading of "2017-01-09", and so on. I need to keep the dates as data, so setting my own headers for the csv file programmatically is perfectly fine.
I am not able to use any add ins for visual studio such as JSON.Net, so the built in tool only or some other work around.
Thank you

You can deserialise to a Dictionary, something like this:
public class InnerThing
{
public int Chats { get; set; }
public int Missed_Chats { get; set; }
}
var result = JsonConvert.DeserializeObject<Dictionary<string, InnerThing>>(json);

Related

problem deserializing object using newtonsoft

I hope someone can help me. This is code I use to retrieve a bunch of data about a particular device with an api (in this case, a Twinkly light string).
Here's my code, which is partially functional.
HttpResponseMessage result = await httpClient.GetAsync(uri);
string response = await result.Content.ReadAsStringAsync();
JObject jObject = JObject.Parse(response);
Layout layout = new Layout();
layout = JsonConvert.DeserializeObject<Layout>(response);
I say it's "partially" functional because every property that is in the root level deserializes into the model just fine, but the json also returns a property called "coordinates" which consists of an array entry for each bulb, and each entry has three values for x,y,z.
I have tried a lot of stuff to get the data from the coordinates array and i can break-mode view that the data is in there.
However it doesn't deserialize properly. I have the correct number of elements in the coordinates array, but they are all x:0, y:0, z:0
Here is my model schema. I hope someone can help me with this. This is my first foray into api work, and the first time i've had a nested model like this.
internal class Layout
{
public int aspectXY { get; set; }
public int aspectXZ { get; set; }
public LedPosition[] coordinates { get; set; }
public string source { get; set; } //linear, 2d, 3d
public bool synthesized { get; set; }
public string uuid { get; set; }
}
internal class LedPosition
{
double x { get; set; }
double y { get; set; }
double z { get; set; }
}
Note: I've tried assigning the properties manually like this:
JToken dataToken = jObject.GetValue("coordinates");
and that indeed received the data but it didn't help me as it merely moved the issue.
you don' t need parse and deserialized in the same time, it would be enough
var response = await result.Content.ReadAsStringAsync();
var layout = JsonConvert.DeserializeObject<Layout>(response);
to make LedPosition properties visible make them public too
public class LedPosition
{
public double x { get; set; }
public double y { get; set; }
public double z { get; set; }
}
since it is used by another class this class should be public too
public class Layout
One thing I've learned recently from the big dog CTO at my work was you can actually copy the JSON you're expecting, and go to Edit -> Paste Special -> Paste JSON as Classes in Visual Studio and it'll paste it as the classes you need, with the proper names/properties. Really slick. Maybe try that and see if it comes out with a different model than what you have now.
This is my first foray into api work
Two things I want to point out, then..
does the api you're using publish a swagger/open api document?
No - see 2 below
Yes - take a look at tools like NSwag(Studio), Autorest and others. You feed the swagger.json into them and they crank out a few thousand lines of code that creates a client that does all the http calling, deserializing, the classes of data etc. if means your code would end up looking like:
var client = new TwinklyLightClient();
var spec = client.GetTwinklyLightSpec();
foreach(var coord in spec.Coords)
Console.Write(spec.X);
This is how APIs are supposed to be; the tools that create them operate to rules, the tools that describe them operate to rules so the consumption of them can be done by tools operating to rules - writing boilerplate json and http request bodies is a job for a computer because it's repetitive and always follows the same pattern
The API doesn't publish a spec we can use to get the computer to write the boring bits for us. Durn. Well, you can either make the spec yourself (not so hard) or go slightly more manual
Take your json (view it raw and copy it)
Go to any one of a number of websites that turn json into code - I like http://QuickType.io because it does a lot of languages, has a lot of customization and gives advanced examples of custom type deser, but there are others - and paste that json in
Instantly it's transformed into eg C# and can be pasted into your project
It gives an example of how to use it in the comments - a one liner something like:
var json = httpCallHereTo.GetTheResponseAsJsonString();
var twinklyLightSpec = TwinklyLightSpec.FromJson(json);
Yes, visual studio can make classes from json, but it's not very sophisticated - it does the job, but these sites that make json to c# go further in allowing you to choose arrays or lists, what the root object is called, decorating every property with a JsonProperty attribute that specifies the json name and keeps the c# property to c# naming conventions (or allows you to rename it to suit you)..
..and they work out of the box, which would resolve this problem you're having right now

System.Text.Json access Json object of json object using c# .net core 3.1

I am calling an api where result is coming this way {{'orderNo':123456}}
the same I am trying to access through these codes lines and But it is not working:
using System.Text.Json.JsonDocument doc = System.Text.Json.JsonDocument.Parse(payment["notes"]);
What I feel it should be very easy to access. Well, I just don't want to create any DTO for the same.
FYI, I can achieve this using DTO class like this:
RzOrderDto orderNo = System.Text.Json.JsonSerializer.Deserialize<RzOrderDto>(payment["notes"].ToString(),null);
public class RzOrderDto {
public string orderno { get; set; }
}
Now, here I don't want to use any object class but just want value of orderNo
{{'orderNo':123456}} is not a valid Json document, you should try to change the data that is coming from the API. If you cannot do that, you need to get rid of the outer pair of braces before parsing the string into an object.

Filter c# object with JObject

Let me preface by saying I'm very new to C# development so if the solution seems obvious I apologize.
I'm getting a JSON string back from a user and I need to filter a list of C# objects based on what the JSON string contains. The JSON can only have fields that my C# model has but I don't know what fields the JSON string will contain. My C# model looks something like this:
public class Enrollment {
public int Year { get; set; }
public int NumEnrolls { get; set; }
public int DaysIntoEnrollment { get; set; }
public string Name { get; set; }
}
The JSON will have one or more of these properties with values to filter out. It could look like this:
{
"Year": ["2020", "2019"],
"Name": ["CourseA", "CourseB"],
"DaysIntoEnrollment": "20"
}
I need to filter my list of Enrollment objects based on the above JSON. So I would want the end result to have all Enrollment objects that don't contain a Year of 2020 or 2019 for example.
I've gotten a filter to work with linq on a single property but my real model has much more properties that can be filtered and I'm looking for a compact solution that will work regardless of which properties are included in the JSON. This is what I have working
public void GetFilteredData(string filters) {
var enrollList = new List<Enrollments>(); // Pretend this contains a list of valid Enrollment data
var json = JObject.Parse(filters); // filters string is in the json format from above
var propsToFilter =
from p in json["Year"]
select p;
var filtered = enrollList.Where(e => !propsToFilter.Contains(e.Year.ToString())));
}
Is there a simple way to do this without manually going through each property like I did above?

How to auto generate/create SQL server table from JSON in C#

I am getting JSON of Form Data from users. Below is the example of JSON Data
{
"Name":"Mike",
"Age":25,
"Gender":"Male",
"Skills":{
".Net":true,
"Mule":""
}
}
I want to save this data in a table (SQL Server). There is no table in the database, I want to define table name before sending this data to sql. Is there any approach to achieve this. Please help.
I suggest using json2csharp to convert the JSON to C# models and alter the names which are not recognized
public class Skills
{
[JsonProperty(PropertyName = ".Net")] //Add JsonProperty to include unclassified names
public bool DotNet { get; set; }
public string Mule { get; set; }
}
public class RootObject10
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public Skills Skills { get; set; }
}
then, you can deserialize the json using JsonConvert
using (StreamReader r = new StreamReader(filepath))
{
string json = r.ReadToEnd();
var obj = JsonConvert.DeserializeObject<RootObject10>(json);
}
After this, based on your requirement create single data table or 2 data tables and inject the data
Assuming your question is not about how to translate json into c# object but rather about how to store it in SQL Server while still being able to query it, you can actually work with json data in sql server: https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver15.
I would opt for something like that if I didn’t have schema upfront or I knew it will change often. Then I would create a table called FormData with an Id and Data fields and just stored your JSON in there.
Bear in mind this is likely less performant than defining tables and properly parsing json (which is covered by other answers here) - make sure you make the call after you’ve considered all pros and cons of schema-less storage.
Upd: if you absolutely must create tables at runtime you could potentially run plain SQL DDL statements like ´CREATE TABLE´ using plain ADO.NET

Can I consume JSON without defining the fields before in C# code?

I am working on a REST API for a project using Visual Studio 2013 with C# and ASP.NET, and I need some guidance.
When the webpage performs a POST, I am passing along a number of fields as a JSON object. By defining a data transfer object in my C# code, I can easily read the values from the JSON, but only if I define all the fields (with the same name).
Here is my current (working) code:
public class AgencyPostDTO
{
public string AgencyName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZIP { get; set; }
}
// POST: api/Agency
public string Post(AgencyPostDTO Agency)
{
int success;
success = SQLUpdateAgency(Agency);
if (success < 1)
{
return "Failed";
}
else
{
return "Success";
}
}
So far no problems. I need to pass the data over to a second function, where I will perform some data processing (including converting the data into XML) and send the data/XML to MS SQL using a stored procedure:
public int SQLUpdateAgency(AgencyPostDTO Agency)
{
string xml = Agency.SerializeObject();
... code to call SQL stored procedure ommitted here
}
Now to my problem. I would prefer if I did not have to define the parameters of the data transfer object AgencyPostDTO in the code, and instead the code would just read the incoming JSON and pass it along to the next function, where I create the XML containing everything passed along.
As it works now, if the JSON contains for example an email address field, it will be dropped unless I define it in AgencyPostDTO.
So why do I want to do this? For future ease of maintenance. The users may come and say they want to add additional fields to the web form. I can then simply have our SQL expert add that column to the table, give me the name of it and I add an input field to the HTML form and make sure it is included in the JSON sent over. That way we never have to touch the already written, tested and working code. The new field is simply passed though the whole process.
Can this be done? If so, any suggestions on how?
If you used JSON.NET to handle the deserialisation of your objects then that has support for dynamic properties. Once you'd read your JSON string, you could convert it to a JArray or JObject and from there by using the .Children() call to get a list of all properties to convert it to any XML object you needed.
Have a look here:
Deserialize json object into dynamic object using Json.net

Categories