C# Create a .NET object for JSON serialization and deserialization [duplicate] - c#

This question already has answers here:
How do I turn a C# object into a JSON string in .NET?
(15 answers)
Closed 6 years ago.
I'm working on a point system for my twitch chat bot in C#. I need to save a list of users with their amount of points and hours to a local .txt file like this:
users : ???
username : ???
nick : string
points : int
hours : int
username : ???
nick : string
points : int
hours : int
username : ???
nick : string
points : int
hours : int
I'm trying to create a .NET Object to serialize to a JSON string and write this to my .txt file but I'm stuck here.
I figure users needs to be an Array of some sort but what do I do with username? I don't think JSON supports custom types?
Thanks for your time,
X3ntr

First we need to create a model. This model needs to match the structure of the JSON. There are a couple of ways to create this model.
Probably the best and safest way is to write it manualy. If you are using vs2015 you can also copy the json and paste it as class.
You can find this option here:
Another option is to use a website like http://json2csharp.com/ here you can paste the JSON and this will also generate classes for your JSON. Keep in mind that these generator are not 100% accurate so you might have to change some properties your self.
Ones we got the model we can use a lib like JSON.net to Deserialize our JSON. On the website is also some extra documentation on how to use JSON.net
var userList = JsonConvert.DeserializeObject<List<UserModel>>(users); //Users being the json as text.
Remember that if you miss a property in you model this will not always throw an error. So make sure that all properties got serialize correctly.
Serializing is as simple as Deserializing.
string json = JsonConvert.SerializeObject(model);
File.WriteAllText("C:\json.txt",json);
Optional is adding an encoding when writing the json.
File.WriteAllText("C:\json.txt",json,Encoding.UTF8);

I'll take a shot at it.
First up we'll need a model for our user:
public class User
{
public Guid Id { get; set; }
public string Username { get; set; }
public string NickName { get; set; }
public int Points { get ;set; }
public int Hours { get; set; }
}
Then in your main method, or wherever you deal with your users:
List<User> users = new List<User>();
Notice that I've added an Id property. Even though your usernames might very well be unique, it's always good practice to have some sort of property whose entire job is to just be the Id. This property should never change throughout the lifetime of the user. Where username might change one day, the Id will always stay the same.
Anyways, now to turn your list into Json:
string myJsonString = JsonConvert.SerializeObject(users, Formatting.Indented);
Et voila! Your list of users is now in a tidy Json string. The above line of code is from JSON.NET, you can get it as a Nuget package. The full qualification is Newtonsoft.Json.JsonConvert. You can pretty much trust JSON.NET to handle almost anything you throw at it, especially for a simple User class like you're going to be throwing at it.
Hope this helps get you started.

Related

JSON deserialization without using classes? (webservice client)

I am trying to get around that C# prefers to have classes generated (I know they are easy to generate, but currently my format and parameters are changing a lot due to development in both client and server end).
Example of what I most often find when I try to find out to deserialize is that you first have to know the exact structure - then build a class - and then you can refer to it later on (it's fine, but it's just not what I would like to do):
Json format 1:
[{"FirstName":"Bob","LastName":"Johnson"},{"FirstName":"Dan","LastName":"Rather"}]
public class People
{
public string FirstName { get; set; }
public string LastName { get; set;}
}
public List<People> peopleList;
. . . // (same as first example)
//Change the deserialize code to type <List<Class>>
peopleList = deserial.Deserialize<List<People>>(response);
That of course is easy as long as the reply doesn't change format, if for example the reply changes to a nested field :
Json format 2:
[{"FirstName":"Bob","LastName":"Johnson"},{"data":{"nestedfield1"
:"ewr"} }]
I would of course have to change the class to represent that, but at the moment we are moving back and forth in formats and I would somehow like if there was a way where I could try to access json elements directly in the string?
For example, like I can do in Python:
mystring1 = reply ["firstName"] mystring2 = reply ["data"]["nestedfield1"]
Is there any way to achieve this in C#? It would speed up development rapidly if there was a way of accessing it without first referencing the output in the code to then once again reference the class variable that was created when referencing it.
And note it's for rapid development, not necessarily for the final implementation where I can see advantages by doing the class approach.
Another way of asking was maybe can it serialize taking any format (as long as its JSON) and dynamically build up a struct where I can access it with named keys and not as class variables?
to deserialize json without using classes you can use using Newtonsoft.Json
here's the code:
using System;
using Newtonsoft.Json;
using System.Text;
public class Program
{
public static void Main()
{
var myJSONString = "[{\"FirstName\":\"Bob\",\"LastName\":\"Johnson\"},{\"FirstName\":\"Dan\",\"LastName\":\"Rather\"}]";
dynamic obj = JsonConvert.DeserializeObject<dynamic>(myJSONString);
Console.WriteLine(obj[0].FirstName);
}
}
The obj will perform the same way you use when generating classes,
it can take any json string and deserialize into dynamic object regardless of structure of the json. Keep in mind that you won't get VS intellisense support.
UPDATE
Here's fiddle:
https://dotnetfiddle.net/xeLDpK

parse string to json object in wpf?

I have a json String(array) like this:
[{"user":{"name":"abc","gender":"Male","birthday":"1987-8-8"}},
{"user":{"name":"xyz","gender":"Female","birthday":"1987-7-7"}}]
and want to parse it to json object using .net4.0 framework only, and i cannot use DataContractJsonSerializer as it requires class and i am receiving dynamic data over web services within 1 minute which keep changing and it is in Name-value format,i tried using JavaScriptSerializer but i am unable to add system.web.extension in my vs2010 project .net4.0 supported framework,and i don't want to use any third party library,actually i am New-bie in wpf,so please it would be great help,thanks in advance!
Well there are two main issues I can see here, and one additional.
1) If you do not have particular class that you could deserialize JSON to, then you have to rely on some "dictionary-like" structure (e.g. dynamic or JToken)to be able to access all fields. However data you presented seems to be structured, so maybe consider creating POCO to get advantage of strongly-typed structure. Both can be easily achieved using ready-to-use libraries.
2) You say you don't want to use any third party library, but actually there is nothing wrong with it. Actually you should be doing so to avoid reinventing the wheel as Tewr mentioned. It's perfectly fine to use in fact industry-standard library such as Newtonsoft Json so you can avoid tons of bugs, unnecessary work and future troubles. If your point is to learn by writing JSON (de)serializer it's perfectly fine, but I'd recommend against using it in production code.
Side note: you mentioned you receive data over web-service, and it seems you receive simply JSON array (as top-level object). It's considered as security hole. More information may be found here:
https://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
What are "top level JSON arrays" and why are they a security risk?
EDIT 2017-11-05:
Ok, so you should create classes representing response from your web service (you can use feature of VS called Edit > Paste Special > Paste JSON As Classes):
public class Response
{
public User[] users { get; set; }
}
public class User
{
public string Name { get; set; }
public string gender { get; set; }
public string birthday { get; set; }
}
Now using Nuget install package Newtonsoft.Json and using following code you'll deserialize JSON response to .NET classes:
string responseText = "";//Get it from web service
var response = JsonConvert.DeserializeObject<Response>(responseText);
Hope this help!

Passing complex type containing array of complex types to Web API

Extending on from this question, I'm trying to pass a complex object containing a collection of complex objects to an ASP.NET Web API controller action method, but I'm having trouble finding the correct format to use for my input object in the request. Continuing the example from Christopher Johnson's question (and removing some fields for simplicty), if I change his PhoneRequest object to contain a collection of phone numbers...
public class PhoneRequest
{
public string[] PhoneNumbers { get; set; }
public string State { get; set; }
}
...and I either pass the parameter as a URL encoded query string:
/api/phonenumber?id[0][State]=UT&id[0][PhoneNumbers][0]=555-1234567
...or POST it as a html form encoded (Content-Type: application/x-www-form-urlencoded) request body:
[0][State]=UT&[0][PhoneNumbers][0]=555-1234567
...then everything works great. But If I change PhoneNumbers from a collection of strings to a collection of a new PhoneNumber type...
public class PhoneRequest
{
public PhoneNumber[] PhoneNumbers { get; set; }
public string State { get; set; }
}
public class PhoneNumber
{
string AreaCode { get; set; }
string Number { get; set; }
}
...and I pass the object in what appears to me to be the logical way, given the previous result...
id[0][State]=UT&id[0][PhoneNumbers][0][AreaCode]=555&id[0][PhoneNumbers][0][Number]=1234567
...or again as a html form post body...
[0][State]=UT&[0][PhoneNumbers][0][AreaCode]=555&[0][PhoneNumbers][0][Number]=1234567
...then it still makes an attempt to bind it, and gets into my action method, but the model only contains State, and the phone number is this weird ComplexUriAndFormObject thing. Here's a copy-paste from my debugger Watch:
phoneRequest {ComplexUriAndFormObject.Models.PhoneRequest[1]}
[0] {ComplexUriAndFormObject.Models.PhoneRequest}
PhoneNumbers {ComplexUriAndFormObject.Models.PhoneNumber[1]}
[0] {ComplexUriAndFormObject.Models.PhoneNumber}
AreaCode null
Number null
State "UT"
Is there some way to specify this object correctly using this format? Or have I exceeded the limit of what ASP.NET Web API's built in model binders are able to do?
Note: Please don't say "just use POST" or "just use JSON/XML/Whatever as your Content-Type"... If I was able to do that, I would.
Until now, no built-in Web API model binders including derived FromUri and FromBody attributes support passing a complex object that contains any property of non-primitive class types (excluding the System.String) with query strings. I had the similar issues and have created a unique and advanced custom model binder, the FieldValueModelBinder class, to work on a target object hierarchy having generic list or array collections. I can use the pure query string type of source data without imbedding any JSON or XML structure into it. The model binder can be used as easy as the FromUri and FromBody attributes. It also works effectively for transferring query string data in both URI and request body.
Please read my article and download source code I have just posted using this link. You can also run the test app from the download source for your input string, model, and results. I hope that this is the right solution you need.

C# Deserialize Complex Object From QueryString

I'm forced to use GET requests to pass complex objects to my application.
How can I deserialize a querystring like this:
?people[andy]=12&people[bob]=43&people[charlie]=53&items=89&items=123&x=zulu
into a custom object like this?
public class myClass {
public Dictionary<string, int> people { get; set; }
public int[] items { get; set; }
public string x { get; set; }
}
Is there a better (more sophisticated) way to do this besides splitting it by & and looping through the results to manually set each value?
Any pointers / guidance would be greatly appreciated.
If you have control over the sending side of the application, I strongly suggest you use a different encoding method to make parsing easier. I would just JSON encode the entire object, and then URIencode the JSON if it must be in the query_string.
There are often fairly small (on the order of 2K characters) limits to the size of URIs including the query_string. If you are forced to use HTTP, depending on your use case and whether you have control over this, POST may be preferable.
See this question for some methods of deserializing JSON:
C# deserialize dynamic JSON

C# Parsing json into generic collection

Parsing Google Plus JSON objects
Using C# and Newtonsoft.Json library how one can parse following json code?
[["tsg.lac",
[[["3a4a7e8e0b3d5d66"],["Friends",null,"Your real friends, the ones you feel comfortable sharing private details with.",null,null,null,null,null,null,2,2,null,"00000000",1,1,1]]
,[["5947b6d78a8231f3"],["Family",null,"Your close and extended family, with as many or as few in-laws as you want.",null,null,null,null,null,null,2,2,null,"00000001",2,1,1]]
,[["22d0e3ec8c38fa24"],["Acquaintances",null,"A good place to stick people you've met but aren't particularly close to.",null,null,null,null,null,null,2,2,null,"00000002",5,1,1]]
,[["1adf9b0b0987c2ad"],["Following",null,"People you don't know personally, but whose posts you find interesting.",null,null,null,null,null,null,2,2,null,"00000003",6,1,1]]
,[["15"],["Blocked",null,null,null,null,null,null,null,null,2,1,null,"z9",null,1,1]]]
,[]
]
]
Basically how do you parse Json if you do not know the original structure?
Is it possible to parse it into generic key/value collection?
You can parse it like
JArray jobj = (JArray)Newtonsoft.Json.JsonConvert.DeserializeObject(jStr);
foreach (var x in jobj[0][1])
{
Console.WriteLine(x[0][0] + " " + x[1][2]);
}
and the output will be
3a4a7e8e0b3d5d66 Your real friends, the ones you feel comfortable sharing private details with.
5947b6d78a8231f3 Your close and extended family, with as many or as few in-laws as you want.
22d0e3ec8c38fa24 A good place to stick people you've met but aren't particularly close to.
1adf9b0b0987c2ad People you don't know personally, but whose posts you find interesting.
PS: JsonView is a very good tool to help you
I think the answer depends on what you want to do with the data. If you are looking to extract specific pieces of information, I would build a class that contains the elements that you are looking to use and has placeholders for the rest, then deserialize into that class.
You can verify that the class is constructed correctly by first serializing a sample class and verifying that it produces the same output as what you are trying to parse.
You could use
JsonConvert.DeserializeObject<ElementType>("your json string here");
where the ElementType must be defined for your json data, could be something like:
[Serializable]
public class ElementType
{
public string ConstituentID { set; get; }
public string Email { set; get; }
}
(this one i pulled from somewhere and it does not correspond to you JSON structure)
Ie. it must capture your JSON structure.

Categories