How to save the Inventory in a JSONString in C# - c#

so today I tried to create a class for my inventory and add items to it. I created 2 classes, one with my inventory: name,amount,slot and one with a list List<Inventory>. But it always showed exceptions with this code:
public class Inventory
{
public string name { get; set; }
public int amount { get; set; }
public int slot { get; set; }
}
public class InventoryList
{
public List<Inventory> invList = new List<Inventory>();
}
In my startup code i serialized it,which worked, but i tried to deserialize it, and it threw exceptions.
Inventory inventory = new Inventory() { name = "Burger", amount = 1, slot = 2 };
string jsonString = JsonSerializer.Serialize(inventory);
So first of all, when i try to get the items in the list i get this error:
What i want: I want a clear JSON-String, which i can deserialize in C#.
i want, that the list looks like this:
[
{
"name":"cheese",
"amount":5,
"slot":1,
},
{
"name":"Bread",
"amount":2,
"slot":4,
},
]

You basically want to serialize/deserialize a LIST of objects. Here's a working example:
Inventory inventory = new Inventory() { name = "cheese", amount = 5, slot = 1 };
Inventory inventory2 = new Inventory() { name = "Bread", amount = 2, slot = 4 };
var inventoryList = new List<Inventory>()
{
inventory,
inventory2
};
var options = new JsonSerializerOptions()
{
WriteIndented = true
};
string jsonString = JsonSerializer.Serialize(inventoryList, options);
Console.Write($"Serialized list {jsonString} {Environment.NewLine}");
var list = JsonSerializer.Deserialize<List<Inventory>>(jsonString);
Console.Write($"Deserialization completed");
Result:
The example above matches the JSON structure that you said you need.
If you still need an object wrapper it should work like this:
class Program
{
static void Main(string[] args)
{
Inventory inventory = new Inventory() { name = "cheese", amount = 5, slot = 1 };
Inventory inventory2 = new Inventory() { name = "Bread", amount = 2, slot = 4 };
var invList = new List<Inventory>()
{
inventory,
inventory2
};
InventoryList inventoryList = new InventoryList() {invList = invList };
var options = new JsonSerializerOptions()
{
WriteIndented = true
};
string jsonString = JsonSerializer.Serialize(inventoryList, options);
Console.Write($"Serialized list {Environment.NewLine} {jsonString} {Environment.NewLine}");
var list = JsonSerializer.Deserialize<InventoryList>(jsonString);
Console.Write($"Deserialization completed");
}
}
public class Inventory
{
public string name { get; set; }
public int amount { get; set; }
public int slot { get; set; }
}
public class InventoryList
{
public List<Inventory> invList { get; set; }
}
Note the change for invList. It's a get/set property now.
However, this wrapper will add another layer of curly brackets to your json:
Result:

You're trying to Deserialize Inventory type and assign the result object to InventoryList

You can learn from this sample (different json format)
public class Inventory
{
public string name { get; set; }
public int amount { get; set; }
public int slot { get; set; }
}
public class InventoryList
{
public List<Inventory> invList { get; set; }
}
//SAMPLE 1
InventoryList lInventory = new InventoryList()
{
invList = new List<Inventory>
{
new Inventory {name = "cheese", amount = 5, slot = 1 },
new Inventory {name = "Bread", amount = 2, slot = 4 }
}
};
//it will produce
//{"invList":[{"name":"cheese","amount":5,"slot":1},{"name":"Bread","amount":2,"slot":4}]}
string jsonString = JsonSerializer.Serialize(lInventory);
//How to deserialize
InventoryList inventoryList = (InventoryList)JsonSerializer.Deserialize<InventoryList>(jsonString);
//SAMPLE 2
List<Inventory> invList = new List<Inventory>
{
new Inventory {name = "cheese", amount = 5, slot = 1 },
new Inventory {name = "Bread", amount = 2, slot = 4 }
};
//it will produce
//[{"name":"cheese","amount":5,"slot":1},{"name":"Bread","amount":2,"slot":4}]
string jsonString2 = JsonSerializer.Serialize(invList);
//How to deserialize
List<Inventory> inventoryList2 = (List<Inventory>)JsonSerializer.Deserialize<List<Inventory>>(jsonString2);

Related

How to convert a list to JSON in C#?

I have a City_State list:
City_State[0].Range="\"city\":\"REDMOND\",\"state\":\"AK\"";
City_State[1].Range="\"city\":\"Alex City\",\"state\":\"
How to convert it into json like below:
var _pairs = new
{
criteria = new { cities = new[] { new { city = "REDMOND", state = "WA" },
new { city = "Alex City", state = "AL" } }
} ;
I tried the code below, but it does not work:
var _pairs = new { criteria = new { cities = new[] { _paged_City_State.ToArray() } } };
If you had these classes:
public class CityStateRaw
{
public string Range { get; set; }
}
public class CityState
{
public string City { get; set; }
public string State { get; set; }
}
The following code would work:
var ranges = new[]
{
new CityStateRaw { Range = "{\"city\":\"REDMOND\",\"state\":\"AK\"}" },
new CityStateRaw { Range = "{\"city\":\"Alex City\",\"state\":\"foo\"}" },
};
var list = ranges
.Select(raw => JsonConvert.DeserializeObject<CityState>(raw.Range))
.ToList();
But if this doesn't match your expectations you should be more concrete about what your exact input and the expected output should be.

Query mongo document array

I have the next mongo document structure :
_id
-countryCode
-keywordID
-name
-displayName
-categories:[Array]
-_id
-name
-position
-canonical
I would like to get all the keywords that are in a specific category only knowing the category's ID. I am using the mongo C# driver but don't know how could I check what's inside that array.
I would like to send a list with the category ID's and get back all the keywords that have a category from that list.
public async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
{
var mongoCollection = MongoDatabase.GetCollection<Keyword>("Keywords");
try
{
FilterDefinition<Keyword> mongoFilter = Builders<Keyword>.Filter.In(c=>c.Categories, keywordCatIds);
return await mongoCollection.Find(mongoFilter,null).ToListAsync<Keyword>();
}
catch (Exception ex)
{
Logger.Error(ex, "Multiple ids for Country Code: {0}, ids: {1}", countryCode, string.Join(',', keywordCatIds.Select(s => s)));
return null;
}
}
Your In function looks like a "categories._id" filter in normal mongoDB. Which transitions into an ElemMatch. I created a project which fills the db, than selects
all the keywords that are in a specific category only knowing the category's ID
public class CustomID
{
public string CountryCode { get; set; }
public long KeywordId { get; set; }
public string Name { get; set; }
}
public class Keyword
{
[BsonId]
public CustomID Id { get; set; }
public List<Category> Categories { get; set; }
}
public class Category
{
[BsonId]
public long Id { get; set; }
public string Name { get; set; }
public int Position { get; set; }
}
internal class Program
{
public static IMongoDatabase MongoDatabase { get; private set; }
public static async Task Main()
{
var conventionPack = new ConventionPack
{
new CamelCaseElementNameConvention()
};
ConventionRegistry.Register(
"CustomConventionPack",
conventionPack,
t => true);
var client = new MongoClient();
MongoDatabase = client.GetDatabase("SO");
var ret = await GetKeywords(new List<long> {1L, 2L}, "HU-hu");
// ret is A and B. C is filtered out because no category id of 1L or 2L, D is not HU-hu
}
public static async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
{
var mongoCollection = MongoDatabase.GetCollection<Keyword>("keywords");
// be ware! removes all elements. For debug purposes uncomment>
//await mongoCollection.DeleteManyAsync(FilterDefinition<Keyword>.Empty);
await mongoCollection.InsertManyAsync(new[]
{
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 1L, Name = "CatA", Position = 1},
new Category {Id = 3L, Name = "CatC", Position = 3}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 1,
Name = "A"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 2L, Name = "CatB", Position = 2}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 2,
Name = "B"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 3L, Name = "CatB", Position = 2}
},
Id = new CustomID
{
CountryCode = "HU-hu",
KeywordId = 3,
Name = "C"
}
},
new Keyword
{
Categories = new List<Category>
{
new Category {Id = 1L, Name = "CatA", Position = 1}
},
Id = new CustomID
{
CountryCode = "EN-en",
KeywordId = 1,
Name = "EN-A"
}
}
});
var keywordFilter = Builders<Keyword>.Filter;
var categoryFilter = Builders<Category>.Filter;
var mongoFilter =
keywordFilter.ElemMatch(k => k.Categories, categoryFilter.In(c => c.Id, keywordCatIds)) &
keywordFilter.Eq(k => k.Id.CountryCode, countryCode);
return await mongoCollection.Find(mongoFilter).ToListAsync();
}
}

Class Serialization Design

I need to serialize 3 different objects into 3 different XMLs. Further, i will deserialize it.
My Class Design:
class Program
{
public static void Main()
{
CarsPersistence cars = new CarsPersistence()
{
Cars = new Car[]
{
new Car{ Name = "Car1", Speed = 201},
new Car{ Name = "Car2", Speed = 202},
new Car{ Name = "Car3", Speed = 203},
new Car{ Name = "Car4", Speed = 204},
new Car{ Name = "Car5", Speed = 205},
}
};
WaysPersistence ways = new WaysPersistence()
{
Ways = new Way[]
{
new Way{Number = 100, Length = 200 },
new Way{Number = 101, Length = 201 },
new Way{Number = 102, Length = 202 },
new Way{Number = 103, Length = 203 },
new Way{Number = 104, Length = 204 },
new Way{Number = 105, Length = 205 },
new Way{Number = 106, Length = 206 },
new Way{Number = 107, Length = 207 },
}
};
CarsWaysPersistence carsWays = new CarsWaysPersistence()
{
CarsWays = new KeyValuePair<Car, Way>[]
{
new KeyValuePair<Car, Way>(cars.Cars[0], ways.Ways[2]),
new KeyValuePair<Car, Way>(cars.Cars[3], ways.Ways[1])
}
};
}
}
[Serializable]
public class Car
{
public int Speed { get; set; }
public string Name { get; set; }
}
[Serializable]
public class CarsPersistence
{
public Car[] Cars { get; set; }
}
[Serializable]
public class Way
{
public int Number { get; set; }
public int Length { get; set; }
}
[Serializable]
public class WaysPersistence
{
public Way[] Ways { get; set; }
}
public class CarsWaysPersistence
{
public KeyValuePair<Car, Way>[] CarsWays { get; set; }
}
I will serialize 3 persistence classes (CarsPersistence, WaysPersistence, CarsWaysPersistence) in different XML files.
My problem is duplication: CarsWaysPersistence have Car and Way objects which are already consists in other XML files. Probably, i can not save reference in XML file.
How this duplication can be solved.
Thanks
1) Serialize all cars.
2) Serialize all ways.
3) Use Name of the car as a unique identifier. You have to provide some unique key to Way as well. This would allow you to map them by the key: <car_name, way_key>.

Unable to deserialize JSON array

Below is my class :
public class Employee : Base
{
public int Id { get; set; }
public string Fname { get; set; }
public DepartmentModel Department { get; set; }
}
public class DepartmentModel : Base
{
public int Id { get; set; }
public string DepartmentName { get; set; }
public List<Location> Locations { get; set; }
}
public class Locations
{
public string Area { get; set; }
public string StreetNo { get; set; }
public string Nearby { get; set; }
}
Response return from service:
var response = new
{
id = 100,
department = new
{
id = 200,
departmentName = "Abc",
locations = new[]
{
Employee.Department.Locations
.Select
(
lo => new
{
area = lo.Area,
streetNo = lo.streetNo,
nearby = lo.Nearby
}
).ToList()
}
}
};
return JsonConvert.SerializeObject(response);
Now when I try to deserialize this above JSON into my class Employee like below:
var deserialize = JsonConvert.DeserializeObject<Employee>(response.ToString());
Error:
How can I deserialize this above JSON?
The problem lies here:
locations = new[]
{
Employee.Department.Locations
.Select
(
lo => new
{
area = lo.Area,
streetNo = lo.streetNo,
nearby = lo.Nearby
}
).ToList()
}
The LINQ expression ends with .ToList() and thus is already returning a list of items. You are then wrapping that with new[] in an array. So, instead of being an array of Locations, the JSON is an array of an array of Locations.
Try removing the new[]. You don't want locations to be an array of lists
locations = Employee.Department.Locations
.Select(lo => new
{
area = lo.Area,
streetNo = lo.streetNo,
nearby = lo.Nearby
}
).ToList()
You need to instantiate a new Employee() and use the same casing as the classes:
var response = new Employee() // Instantiates Employee to ensure correct properties used.
{
Id = 100, // Has PascalCase.
Department = new DepartmentModel()
{
Id = 200,
DepartmentName = "Abc",
Locations = Employee.Department.Locations
.Select(lo => new Location
{
Area = lo.Area,
StreetNo = lo.StreetNo,
Nearby = lo.Nearby
}
).ToList()
}
};

how to create a json format using json.net in c#

I need a final json format as follows and that should be dynamic.
{
"product_items" :
[
{
"_at" : 1,
"product_id" : "999"
},
{
"_at" : 2,
"quantity" : 2.00
},
{
"_delete_at" : 3
}
]
}
How to create a json format as above in the code._at field is dynamic.sometimes it might be 2 and sometimes it might be 10.I dont have idea on to generate the json dynamically in c#.
class Test
{
public ProductItem[] product_items { get; set; }
class ProductItem
{
public int[] _at { get; set; }
public int[] _delete { get; set; }
public int[] quantity { get; set; }
public string[] product_id{get;set;}
}
}
i have create the the properties for json as above.
I'm using Newtonsoft library
Your class should look more like this:
public class ProductItem
{
public int _at { get; set; }
public string product_id { get; set; }
public double? quantity { get; set; }
public int? _delete_at { get; set; }
}
public class ProductItemObject
{
public List<ProductItem> product_items { get; set; }
}
A example on serializing :
List<ProductItem> list = new List<ProductItem>();
ProductItemObject o = new ProductItemObject { product_items = list };
var item1 = new ProductItem { _at = 1, product_id = "001" };
var item2 = new ProductItem { _at = 2, quantity = 2.00 };
var item3 = new ProductItem { _delete_at = 3 };
list.Add(item1);
list.Add(item2);
list.Add(item3);
string json = JsonConvert.SerializeObject(o, Formatting.Indented);
// json string :
// {
// "product_items": [
// {
// "_at": 1,
// "product_id": "001",
// "quantity": null,
// "_delete_at": null
// },
// {
// "_at": 2,
// "product_id": null,
// "quantity": 2.0,
// "_delete_at": null
// },
// {
// "_at": 0,
// "product_id": null,
// "quantity": null,
// "_delete_at": 3
// }
// ]
//}
An alternative full dynamic that gets u the same Json string without any model :
var jsonObject = new JObject();
dynamic objectList = jsonObject;
objectList.product_items = new JArray() as dynamic;
dynamic item = new JObject();
item._at = 1;
item.product_id = "999";
objectList.product_items.Add(item);
item = new JObject();
item._at = 2;
item.quantity = 2.00;
objectList.product_items.Add(item);
item = new JObject();
item._delete_at = 3;
objectList.product_items.Add(item);
string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObject, Formatting.Indented);
Well, if I understand you properly and you just need to be able to generate that json, the product list should be dynamic with maybe anonymous classes then:
public class Products
{
public Products()
{
product_items = new List<dynamic>();
}
public List<dynamic> product_items { get; set; }
}
products.product_items.Add(new { _at = 1, product_id = "999" });

Categories

Resources