So I'm trying to make this parking ticket system and I'm currently creating these objects manually in the code for testing. Now I've come to the step where my POST request in postman should be able to create an object in the memory of the app. I've got two classes one for a ''Car'' and one for the ''Ticket''.
public class Car
{
public string regNr { get; set; }
public string carBrand { get; set; }
public string carColor { get; set; }
public List<Ticket> ticketlist {get; set;}
public Car()
{
this.ticketlist = new List<Ticket>();
}
public void addNewTicket(Ticket newTicket)
{
ticketlist.Add(newTicket);
}
}
}
public class Ticket
{
public int ticketID { get; set; } = 0;
public DateTime date { get; set; }
public string comment { get; set; }
public int parkingAreaID { get; set; }
public int parkingsOfficerID { get; set; }
}
}
List<Bil> list = new List<Car>();
public void Post([FromBody]Bil val)
{
list.Add(val);
}
The GET requests work and I want to be able to add a new ticket to a registration number by using my post request.
My current output is this;
{
"regNr": "BT66358",
"carBrand": "BMW",
"carColor": "Yellow",
"ticketlist": [
{
"ticketID": 1,
"date": "2020-12-12T17:49:34.4000401+01:00",
"comment": "very bad parking",
"parkingsAreaID": 1,
"parkingsOfficerID": 2
},
{
"ticketID": 2,
"date": "2020-12-12T17:49:34.4000401+01:00",
"comment": "very bad parking",
"parkingsAreaID": 2,
"parkingsOfficerID": 2
}
]
}
---------------UPDATE-----------
Bil = Car
botliste = ticketlist
liste = list
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/q3UaO.png
If I understood you correctly, then most likely you just need to add some attributes, and you get something like this:
List<Car> list = new List<Car>();
[HttpPost]
[HttpPost("SomeRoute")]
public IActionResult Post([FromBody] Car val)
{
if (val == null)
{
return BadRequest("Car data must be filled");
}
if (string.IsNullOrEmpty(val.regNr))
{
return BadRequest("Reg number must be filled");
}
var car = list.FirstOrDefault(c => string.Equals(c.regNr, val.regNr));
if (car != null)
{
car.ticketlist.AddRange(val.ticketlist);
}
else
{
list.Add(val);
}
/// And return IActionResult
return Ok();
}
P.S. Give a description of the Bil type to get a more detailed answer.
upd:
You can also add attributes to the fields of your classes that will validate the values, for example:
...
public class Car
{
[MinLength(6, ErrorMessage = "regNr field must be at least 6 characters")]
public string regNr { get; set; }
...
The "MinLength" attribute indicates that the value for this property is required, and must be at least 6 characters.
More details here: https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations?view=net-5.0
upd2:
This is how I get to invoke this method:
The JSON data is as follows:
{"Sucess":true,
"Code":0,
"Msg":"Sucess",
"Data":{
"UserDayRanking":
{
"UserID":11452112,
"UserCharm":0,
"UserName":"gay",
"UserGender":1,
"UserLevel":36,
"UserPhoto":"http://res.xxx.com/2020/3/16/63719926625601201487545U11452112.jpeg",
"Ranking":0,
"IsNobility":0,
"NobilityType":0,
"NobilityLevel":0,
"UserShowStyle":null,
"LiveLevelUrl":null,
"IsStealth":false},
"DayRankingList":[
{
"UserID":3974854,
"UserCharm":114858,
"UserName":"jack",
"UserGender":1,
"UserLevel":91,
"UserPhoto":"http://res.xxx.com/2020/2/15/63717400601924412312384U3974854.jpeg",
"Ranking":2,
"IsNobility":1,
"NobilityType":1,
"NobilityLevel":3,
"UserShowStyle":
{
"NameColor":100102,
"BorderColor":100403,
"LiangMedal":0,
"DztCountDown":0,
"Mounts":100204,
"LiveLevelCode":0,
"LiveRights":null
},
"LiveLevelUrl":null,
"IsStealth":false
},
{"UserID":6231512,
"UserCharm":22644,
"UserName":"red.girl",
"UserGender":1,
"UserLevel":57,
"UserPhoto":"http://res.xxx.com/2019/11/20/63709843050801519858823U6231512.jpeg",
"Ranking":3,
"IsNobility":0,
"NobilityType":0,
"NobilityLevel":0,
"UserShowStyle":{
"NameColor":0,
"BorderColor":0,
"LiangMedal":0,
"DztCountDown":0,
"Mounts":0,
"LiveLevelCode":0,
"LiveRights":null
},
"LiveLevelUrl":null,
"IsStealth":false}
],
"LiveCharmSwitch":1,
"IsSelf":false
}
}
I want to use c # extraction
"UserID": 3974854,
"UserCharm": 114858,
"UserName": "jack",
"UserID":6231512,
"UserCharm":22644,
"UserName":"red.girl",
That is to extract UserID, UserCharm, UserName,This json has many layers,
What I want after the extraction is,id is sorted in order
id = 1, UserID = 3974854, UserCharm = 114858, UserName = jack
id = 2, UserID = 6231512, UserCharm = 22644, UserName = red.girl
I use the following code, but only extract the first one
string json = #"{"Sucess":true,"Code":0,"Msg":"Sucess","Data":{"UserDayRanking":{"UserID":11452112,"UserCharm":0,"UserName":"gay","UserGender":1,"UserLevel":36,"UserPhoto":"http://res.xxx.com/2020/3/16/63719926625601201487545U11452112.jpeg","Ranking":0,"IsNobility":0,"NobilityType":0,"NobilityLevel":0,"UserShowStyle":null,"LiveLevelUrl":null,"IsStealth":false},"DayRankingList":[{"UserID":3974854,"UserCharm":114858,"UserName":"jack","UserGender":1,"UserLevel":91,"UserPhoto":"http://res.xxx.com/2020/2/15/63717400601924412312384U3974854.jpeg","Ranking":2,"IsNobility":1,"NobilityType":1,"NobilityLevel":3,"UserShowStyle":{"NameColor":100102,"BorderColor":100403,"LiangMedal":0,"DztCountDown":0,"Mounts":100204,"LiveLevelCode":0,"LiveRights":null},"LiveLevelUrl":null,"IsStealth":false},{"UserID":6231512,"UserCharm":22644,"UserName":"red.girl","UserGender":1,"UserLevel":57,"UserPhoto":"http://res.xxx.com/2019/11/20/63709843050801519858823U6231512.jpeg","Ranking":3,"IsNobility":0,"NobilityType":0,"NobilityLevel":0,"UserShowStyle":{"NameColor":0,"BorderColor":0,"LiangMedal":0,"DztCountDown":0,"Mounts":0,"LiveLevelCode":0,"LiveRights":null},"LiveLevelUrl":null,"IsStealth":false}],"LiveCharmSwitch":1,"IsSelf":false}}";
List<Info> jobInfoList = JsonConvert.DeserializeObject<List<Info>>(z);
foreach (Info jobInfo in jobInfoList)
{
//Console.WriteLine("UserName:" + jobInfo.UserName);
}
public class Info
{
public string UserCharm { get; set; }
public string UserName { get; set; }
public data DayRankingList { get; set; }
}
public class data
{
public int UserID { get; set; }
public string UserCharm { get; set; }
public string UserName { get; set; }
public string UserGender { get; set; }
public string UserLevel { get; set; }
}
The above code only shows username = jack,Never show username = red.girl
As it looks to me then you want some details from your JSON has the which is in DayRankingList. As you only want some data then we can use a tool like http://json2csharp.com/ to create our classes and then remove what we don't need. Then we end up with the following classes.
public class DayRankingList
{
public int UserID { get; set; }
public int UserCharm { get; set; }
public string UserName { get; set; }
}
public class Data
{
public List<DayRankingList> DayRankingList { get; set; }
}
public class RootObject
{
public Data Data { get; set; }
}
Which you can deserialise like this
string json = .....
var root = JsonConvert.DeserializeObject<RootObject>(json);
Then if you wish, you can extract the inner data into a new List<> and then just work on that.
List<DayRankingList> rankingLists = root.Data.DayRankingList;
//Do something with this, such as output it
foreach(DayRankingList drl in rankingLists)
{
Console.WriteLine(String.Format("UserId {0} UserCharm {1} UserName {2}",drl.UserId, drl.UserCharm, drl.UserName));
}
You can use Json.Linq to parse your JSON into JObject and enumerate DayRankingList items (since it's an array). Then convert every item into data class and order the result sequence by UserID
var jObject = JObject.Parse(json);
var rankingList = (jObject["Data"] as JObject)?.Property("DayRankingList");
var list = rankingList.Value
.Select(rank => rank.ToObject<data>())
.OrderBy(item => item?.UserID);
foreach (var user in list)
Console.WriteLine($"{user.UserID} {user.UserName}");
Another way is copy your JSON, go to Edit->Paste Special->Paste JSON as classes menu in Visual Studio and generate a proper class hierarchy (I've got 5 classes, they are quite long to post here), then use them during deserialization
The most type-safe way is to define the class structure that you want, like jason.kaisersmith suggested.
To have the final format you need, though, you might want to do an extra Linq Order and Select, to include the id:
var finalList = rankingLists.OrderBy(rl => rl.UserId).Select((value, index) => new
{
id = index,
value.UserId,
value.UserCharm,
value.UserName
});
foreach (var drl in finalList)
{
Console.WriteLine($"Id = {drl.id}, UserId = {drl.UserId}, UserCharm = {drl.UserCharm}, UserName = {drl.UserName}");
}
I am using ASP.net Core web api (c#) here
I have a JSON string as:
{
"userId":321,
"account":"new
"fname":"Adam",
"lname":"Silver"
"features":[
{
"available":true,
"status":open,
"admin":false
}
]
}
I want to test this data in my angular code so wanted to hardcode this into my API; then I want my API to return this back. What I am finding it hard is how to return this. Shall I return this as a string or need to parse it?
I have this method in my API:
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
Do I need to represent this into string or parse it someway?
Your JSON is invalid. We need to correct it. JSONLint can be helpful for that. I took your JSON and corrected the syntax errors until I got this:
{
"userId": 321,
"account": "new",
"fname": "Adam",
"lname": "Silver",
"features":[
{
"available": true,
"status": "open",
"admin": false
}
]
}
Then I need to generate a C# class structure to represent this JSON. I could manually create it, but the excellent json2csharp.com can generate it for me quickly. I fed this JSON into and received the following classes back:
public class Feature
{
public bool available { get; set; }
public string status { get; set; }
public bool admin { get; set; }
}
public class RootObject
{
public int userId { get; set; }
public string account { get; set; }
public string fname { get; set; }
public string lname { get; set; }
public List<Feature> features { get; set; }
}
I put these class definitions into my application. Then I need to modify my action method to create an instance of this RootObject class (you should change the name to actually match what it's intended for).
[HttpGet]
public ActionResult<RootObject> Get()
{
// Create an instance of our RootObject and set the properties
var myRootObject = new RootObject();
myRootObject.userId = 321;
myRootObject.account = "new";
myRootObject.fname = "Adam";
myRootObject.lname = "Silver";
myRootObject.features = new List<Feature>();
// Create an instance of a feature and set its properties
var feature = new Feature();
feature.available = true;
feature.status = "open";
feature.admin = false;
// Add the new feature to the features collection of our RootObject
myRootObject.features.Add(feature);
// Return the instance of our RootObject
// The framework will handle serializing it to JSON for us
return myRootObject;
}
Note that I changed the signature of your method. I made it no longer accept an IEnumerable because it wasn't clear why you had that. And I changed it to return an ActionResult after checking Microsoft's documentation.
Hi Please find correct JSON format for above one:
{
"userId": 321,
"account": "new",
"fname": "Adam",
"lname": "Silver",
"features": [{
"available": true,
"status": "open",
"admin": false
}]
}
you can use below class in your web API to pass respective data
public class Feature
{
public bool available { get; set; }
public string status { get; set; }
public bool admin { get; set; }
}
public class RootObject
{
public int userId { get; set; }
public string account { get; set; }
public string fname { get; set; }
public string lname { get; set; }
public List<Feature> features { get; set; }
}
then at the end, while returning data, convert the respective class object into JSON by serializing that into JSON format.
Hope it will fulfill your requirement.
Putting the comments into an answer:
If you are using ActionResult, I'll assume you are using asp.net mvc. What you want is JsonResult.
[HttpGet]
public JsonResult Get()
{
return new JsonResult
{
Data = new
{
userId = 321,
account = new
{
fname = "Adam",
lname = "Silver",
features = new object[]{
new
{
available = true,
status = "open",
admin = false
}
}
}
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
I am pretty new to coding and here is my requirement:
I am getting a JSON response which has an array of values (refer read,update,delete in the below JSON response)
The number of values is dynamic and tend to vary each time.
I want to know how to retrieve them and put into an string array and return the values
Eg.: end result should be like
string[] deleteValues = {"MCS:Menu:Admin","MCS:test"}
In case if there is answer already available to this question, please point me in the right direction.
Thanks in advance
==========================================
I am able to get the values this way...
string value1 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[0].ToString();
string value2 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[1].ToString();
but since the number of values in delete is dynamic, i need to how to pull them.
====================
the code snippet:
string resp = new StreamReader(request1.GetResponse().GetResponseStream()).ReadToEnd(); // resp is a JSON response from a server
JSON_Deconstructor dc = new JSON_Deconstructor { };
dc.Permitted = new Permitted[1];
string value1 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[0].ToString();
string value2 = new JavaScriptSerializer().Deserialize<JSON_Deconstructor>(resp).Permitted[0].Delete[1].ToString();
==================
JSON_Deconstructor class contents:
public class JSON_Deconstructor
{
public Permitted[] Permitted { get; set; }
public Denied[] Denied { get; set; }
}
==================
Permitted class contents:
public class Permitted
{
public string[] Read { get; set; }
public string[] Update { get; set; }
public string[] Delete { get; set; }
}
=================
JSON response:
{
"Permitted": [
{
"read": [
"MCS:Menu:Admin"
],
"update": [
"MCS:test"
],
"delete": [
"MCS:Menu:Admin",
"MCS:test"
]
}
]
}
First add jsonProperty to your class in order to be able to serialize.
public class Permitted
{
[JsonProperty("read")]
public string[] Read { get; set; }
[JsonProperty("update")]
public string[] Update { get; set; }
[JsonProperty("delete")]
public string[] Delete { get; set; }
}
//Response contains a list of permitted objects in Permitted property
public class PermittedResponse
{
public List<Permitted> Permitted { get; set; }
}
then in you method de serialize your response and loop through results to build your arrays.
List<string> deletedValues = new List<string>();
List<string> readValues = new List<string>();
List<string> updateValues = new List<string>();
PermittedResponse response = JsonConvert.DeserializeObject<PermittedResponse>(serializedJson);
response.Permitted.ForEach(e =>
{
deletedValues = deletedValues.Concat(e.Delete).ToList();
readValues = readValues.Concat(e.Read).ToList();
updateValues = updateValues.Concat(e.Update ).ToList();
});
Use Newtonsoft.Json. You can get it from NuGet. This is very simple and powerful library for Json.
Now, you should create a class, like:
public class Item
{
public List<string> MCS { get; set; } = new List<string>();
}
public class PermitedItem
{
public Item read {get; set;}
public Item update {get; set;}
public Item delete {get; set;}
}
public class MyResponse
{
public List<PermittedItem> Permitted = new List<PermittedItems>();
}
And then you use it like that:
MyResponse result = JsonConvert.DeserializeObject<MyResponse>(jsonAsString);
This should work.
I'm using MongoDB and official C# driver 0.9
I'm just checking how embedding simple documents works.
There are 2 easy classes:
public class User
{
public ObjectId _id { get; set; }
public string Name { get; set; }
public IEnumerable<Address> Addresses { get;set; }
}
public class Address
{
public ObjectId _id { get; set; }
public string Street { get; set; }
public string House { get; set; }
}
I create a new user:
var user = new User
{
Name = "Sam",
Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET" } })
};
collection.Insert(user.ToBsonDocument());
The user is successfully saved, so is his address.
After typing
db.users.find()
in MongoDB shell, I got the following result:
{ "_id" : ObjectId("4e572f2a3a6c471d3868b81d"), "Name" : "Sam", "Addresses" : [
{
"_id" : ObjectId("000000000000000000000000"),
"Street" : "BIGSTREET",
"House" : "BIGHOUSE"
}
] }
Why is address' object id 0?
Doing queries with the address works though:
collection.FindOne(Query.EQ("Addresses.Street", streetName));
It returns the user "Sam".
It's not so much a bug as a case of unmet expectations. Only the top level _id is automatically assigned a value. Any embedded _ids should be assigned values by the client code (use ObjectId.GenerateNewId). It's also possible that you don't even need an ObjectId in the Address class (what is the purpose of it?).
Use BsonId attribute:
public class Address
{
[BsonId]
public string _id { get; set; }
public string Street { get; set; }
public string House { get; set; }
}
Identifying the Id field or property
To identify which field or property of
a class is the Id you can write:
public class MyClass {
[BsonId]
public string SomeProperty { get; set; }
}
Driver Tutorial
Edit
It's actually not working. I will check later why.
If you need get it work use following:
[Test]
public void Test()
{
var collection = Read.Database.GetCollection("test");
var user = new User
{
Name = "Sam",
Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET", _id = ObjectId.GenerateNewId().ToString() } })
};
collection.Insert(user.ToBsonDocument());
}
Get the collection as User type:
var collection = db.GetCollection<User>("users");
Initialize the field _id as follows:
var user = new User
{
_id = ObjectId.Empty,
Name = "Sam",
Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET" } })
};
Then you insert the object:
collection.InsertOne(user);
The _id field will automatically be generated.
In this link you will find alternative ways to have customized auto-generated ID(s).