How can I deserialize this JSON to a C# object? - c#

I'm trying to figure out how to create a C# class that I can deserialize this json into.
Can somebody point me in the right direction?
Here is my json
{
"0": {
"heading": "Home",
"link": "#",
"dropdown": {}
},
"1": {
"heading": "About",
"link": "#",
"dropdown": {
"0": {
"name": "Programs",
"value": "programs"
},
"1": {
"name": "Sample Page",
"value": "test"
},
"2": {
"name": "Donations",
"value": "donations"
}
}
},
"2": {
"heading": "Products",
"link": "#",
"dropdown": {}
},
"3": {
"heading": "Contact Us",
"link": "#",
"dropdown": {
"0": {
"name": "Programs",
"value": "programs"
},
"1": {
"name": "Donations",
"value": "donations"
}
}
}
}
I've tried the following, with no luck
public class Menu
{
public MenuItem MenuItems { get; set; }
}
public class MenuItem
{
public string Heading { get; set; }
public string Link { get; set; }
public DropDownMenu DropDownMenu { get; set; }
}
public class DropDownMenu
{
public string Name { get; set; }
public string Value { get; set; }
}
In my controller I'm using the following to try and deserialize the json into my object.
[HttpPost]
public ActionResult AddMenu(string menuType, string menu, string menuTitle)
{
var serializer = new JavaScriptSerializer();
var newMenu = serializer.Deserialize<Menu>(menu);
}
Note: The menu variable contains the JSON string.

Your current JSON has 4 menu items in it... I am guessing that could change to 5 or 6, right?... if so... your JSON is incorrect, you should use an array.
Something like:
[
{
"heading": "Home",
"link": "#",
"dropdown": []
},
{
"heading": "About",
"link": "#",
"dropdown": [
{
"name": "Programs",
"value": "programs"
},
{
"name": "Sample Page",
"value": "test"
},
{
"name": "Donations",
"value": "donations"
}
]
},
{
"heading": "Products",
"link": "#",
"dropdown": []
},
{
"heading": "Contact Us",
"link": "#",
"dropdown": [
{
"name": "Programs",
"value": "programs"
},
{
"name": "Donations",
"value": "donations"
}
]
}
]
And then define your class:
public class MenuItem
{
public string heading
{
get;
set;
}
public string link
{
get;
set;
}
public DropDownMenu[] dropdown
{
get;
set;
}
}
public class DropDownMenu
{
public string Name
{
get;
set;
}
public string Value
{
get;
set;
}
}
Then you can deserialize your JSON as an "Array of MenuItems"... like:
var ser = new JavaScriptSerializer();
var newMenu = ser.Deserialize<MenuItem[]>(json);
Hope that helps,
Daniel.

From ScottGu's blog:
ASP.NET MVC 3 includes built-in JSON binding support that enables
action methods to receive JSON-encoded data and model-bind it to
action method parameters.
Instead of receiving the parameter as string you could try binding the request directly to your object (json model binding):
[HttpPost]
public ActionResult AddMenu(string menuType, Menu menu, string menuTitle)
{
// use menu here, no need to deserialize anything else
}
Also, make sure the client sends the request's content type as json, for example:
contentType: 'application/json; charset=utf-8',
See Phil Haack's example
Here and here are two more.

Related

Add item to JSON array section in C#

{
"name": "Not Okay Bears Solana #1",
"image": "ipfs://QmV7QPwmfc6iFXw2anb9oPZbkFR75zrtw6exd8LherHgvU/1.png",
"attributes": [
{
"trait_type": "Background",
"value": "Amethyst"
},
{
"trait_type": "Fur",
"value": "Warm Ivory"
},
{
"trait_type": "Mouth",
"value": "Clean Smile"
},
{
"trait_type": "Eyes",
"value": "Not Okay"
},
{
"trait_type": "Hat",
"value": "Bucket Hat"
},
{
"trait_type": "Clothes",
"value": "Plaid Jacket"
},
{
"trait_type": "Eyewear",
"value": "Plastic Glasses"
}
],
"description": "Not Okay Bears Solana is an NFT project for mental health awareness. 10k collection on the Polygon blockchain. We are not okay."
}
I need to add an object to attributes.
How to do this?
My JSON classes:
public class Attribute
{
public string trait_type { get; set; }
public string value { get; set; }
}
public class Root
{
public string name { get; set; }
public string image { get; set; }
public List<Attribute> attributes { get; set; }
public string description { get; set; }
}
try this, in this case you don't need any classes
var jsonObject = JObject.Parse(json);
JObject obj = new JObject();
obj.Add("trait_type", "type");
obj.Add("value", "value");
((JArray)jsonObject["attributes"]).Add(obj);
var newJson=jsonObject.ToString();
but if you need the data not a json , you can use this code
Root data = JsonConvert.DeserializeObject<Root>(json);
data.attributes.Add(new Attribute { trait_type="type", value="value"});

Remove itens from JSON string based on a comparison between two JSON strings - C#

Given 2 JSON strings:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
AND
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
}
]
}
]
First one is the original. The second are the values that I want to remove from the original. So basically, if there is a match on brand and category between first and second JSON, regardless of the order of the elements, I want that match to be removed.
The expected result would be someting like this:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
Catagory A and C in Brand A were removed as well as Category B in Brand B.
Based in some research, I was using https://github.com/wbish/jsondiffpatch.net, tried to work with it's functions, but so far I didn't manage to achieve the result I want. Also, to solve this by processing JSON direcly is not a must. If there is a simpler solution to achieve that by converting them to lists and use something like LINQ for example, it works for me as well (tried that, but didn't manage to find a way to do this comparison).
Thanks in advance.
If performance does not matter, the JsonSerializer and LINQ can be used:
Model
public class JsonModel
{
public class ValueModel
{
public string Id { get; set; }
public string Description { get; set; }
}
public string Id { get; set; }
public string Description { get; set; }
public IEnumerable<ValueModel> Values { get; set; }
}
Deserialize and LINQ
string json1Str = #"[...]";
string json2Str = #"[...]";
var opt = new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var json1 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json1Str, opt);
var json2 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json2Str, opt);
var result = json1.
Join(json2, j1 => j1.Id, j2 => j2.Id, (j1, j2) => new JsonModel
{
Id = j1.Id,
Description = j1.Description,
Values = j1.Values.Where(j1 => !j2.Values.Select(val => val.Id).Contains(j1.Id))
});
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(result, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }));
}
Result
[
{
"Id": "BA",
"Description": "BrandA",
"Values": [
{
"Id": "CategoryB",
"Description": "CategoryB"
},
{
"Id": "CategoryD",
"Description": "CategoryD"
},
{
"Id": "CategoryE",
"Description": "CategoryE"
},
{
"Id": "CategoryF",
"Description": "CategoryF"
},
{
"Id": "CategoryG",
"Description": "CategoryG"
},
{
"Id": "CategoryH",
"Description": "CategoryH"
}
]
},
{
"Id": "BB",
"Description": "BrandB",
"Values": [
{
"Id": "CategoryA",
"Description": "CategoryA"
},
{
"Id": "CategoryC",
"Description": "CategoryC"
}
]
}
]

Json formatting with Json.net in C#

I am trying to parse a bunch of XML files into a single JSON file, which is already working.
The final JSON file looks like the following:
{
"items": [
{
"subItems": [
{
"Name": "Name",
"Value": "Value",
"Type": "text"
},
{
"Name": "Name",
"Value": "Value",
"Type": "text"
}
]
},
{
"subItems": [
{
"Name": "Name",
"Value": "Value",
"Type": "text"
},
{
"Name": "Name",
"Value": "Value",
"Type": "text"
},
...
Instead, I want to achieve the following structure:
{
"items": [
[
{
"Name": "Name",
"Value": "Value",
"Type": "text"
},
{
"Name": "Name",
"Value": "Value",
"Type": "text"
}
],
[
{
"Name": "Name",
"Value": "Value",
"Type": "text"
},
{
"Name": "Name",
"Value": "Value",
"Type": "text"
}
]
]
}
But I don't know how to define my objects in order to do so, my current structure is as follows:
public class Items
{
public List<Item> items;
}
public class Item
{
public List<SubItem> subItems;
}
public class SubItem
{
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
}
How should I do this?
The answer is simple: turn your objects into lists: This will remove the prop names (and object notation in json).
public class Items
{
public List<Item> items; //list with prop name 'items'
}
public class Item : List<SubItem> // list in list like json notation
{
}
public class SubItem // Object in the list in list
{
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
}
As #FlilipCordas noted Inheriting from list is bad practice (for good reason)
you are better of this way:
public class Items
{
public List<List<SubItem>> items; //list with list with prop name 'items'
}
public class SubItem // Object in the list in list
{
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
}
Copy your json then go in Visual Studio.
Click on "Edit" > "Paste Special" > "Paste JSON as Classes"
All the classes are automatically created. I hope this tip could help you.

Swagger ui description of array parameters in .NET

I have controller that recieves object of SearchProfilesModel. It consists of array of SearchProfiles and several properties in base classes.
Method:
[HttpGet]
[ResponseType(typeof(List<UserSearchResult>))]
[Route("SearchWithParams")]
public async Task<HttpResponseMessage>
SearchWithParams([FromUri] SearchProfilesModel model)
{
// Some logic
return Request.CreateResponse(HttpStatusCode.OK, result);
}
Model class:
public class SearchProfilesModel : LoginRequiredModel
{
[Required]
[JsonProperty("search_profiles")]
public List<SearchProfileViewModel> ProfilesList { get; set; }
}
List item class:
public class SearchProfileViewModel
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("surname")]
public string Surname { get; set; }
[JsonProperty("facebook_id")]
public string FacebookId { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
}
I`m using Swagger ui (swashbuckle lib) to test my controllers, but when it generates help page for this method it shows following:
Help page
My question is - can i somehow show structure of list item (from SearchProfileViewModel) in parameters? And if i can - how?
P.S. - Sorry for my English, it`s not my native language.
The structure of your object is in the generated doc, take a look at mine:
http://swashbuckletest.azurewebsites.net/swagger/docs/v1
{
"swagger": "2.0",
"info": {...},
"host": "swashbuckletest.azurewebsites.net",
"schemes": [...],
"paths": {...},
"definitions": {
"Data": {
"type": "object",
"properties": {
"integ": {
"format": "int32",
"type": "integer",
"example": 123
},
"doub": {
"format": "double",
"type": "number",
"example": 9858.216
},
"boolea": {
"type": "boolean"
},
"guid": {
"format": "uuid",
"type": "string",
"example": "f5849915-43c8-434c-92a7-7383d1acb631"
},
"date": {
"format": "date-time",
"type": "string"
}
}
},
...

JSON list of users not binding to model in Web API

I have a JSON object coming into a controller in Web API that isn't binding to my model. I'm testing it using Fiddler, with the following JSON in the body:
{
"userList": {
"user": [
{
"custCode": "test1",
"userName": "TheDude",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Bob",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Ted",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Darryl",
"admin": "false",
"effectiveDate": "2/14/2014"
}
]
}
}
I've included the classes built for the model and the controller method as well.
public class UserList
{
public List<User> userList { get; set; }
}
public class User
{
public string custCode { get; set; }
public string userName { get; set; }
public bool admin { get; set; }
public DateTime effectiveDate { get; set; }
}
[HttpPost]
public void CreateNewUser(UserList newUsers)
{
var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
conn.Open();
try
{
foreach (var user in newUsers.userList)
{
//SQL code is here
}
}
finally
{
conn.Close();
conn.Dispose();
}
}
Its hanging up on the foreach loop, giving me an "Object reference not set to an instance of an object" error. I'm noticing that when it first hits the method, the UserList object is null. I'd appreciate any observations on what I'm doing wrong.
Solved the problem by doing the following:
I changed the UserList class to a string array:
public class UserList
{
public User[] users { get; set; }
}
Then I re-formatted my request body JSON:
{
"users": [
{
"custCode": "test1",
"userName": "TheDude",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Bob",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Ted",
"admin": "false",
"effectiveDate": "2/14/2014"
},
{
"custCode": "test1",
"userName": "Darryl",
"admin": "false",
"effectiveDate": "2/14/2014"
}
]
}
After the changes, I re-tested using Fiddler and everything works as it should.
It should be this way:
public class OuterClass having one private UserList userList and then one more class called:
public class UserList having one private List<User> user
Basically:
public class OuterClass
{
private UserList userList {get; set; }
}
public class UserList
{
private List<User> user {get; set; }
}
If you think some key names in JSON are incorrectly named, even I think so.

Categories

Resources