I have the following JSON data:
{
"count": 2,
"data" : {
"items" : [
{
"id" : "1",
"letterheadline" : "This is a test",
"message" : "testing.. testing..",
"dateEntered" : "2018-01-01 18:00"
},
{
"id" : "2",
"letterheadline" : "Message two",
"message" : "testing.. testing.. testing..",
"dateEntered" : "2018-02-01 18:00"
},
]
}
}
I am trying to parse it into my own object that uses different values, i.e:
public class Message
{
public string title {get; set;}
public string body {get; set;}
public DateTime entryDate {get; set;}
}
public class Messages
{
public int itemCount {get; set;}
public List<Message> messages {get; set}
}
I am using
Messages messages = new JavaScriptSerializer().Deserialize<Messages>(result);
I have tried to use the following:
[JsonProperty("letterheadline")] (for example)
But I am still getting an error saying that it cannot be converted.
Is this because the JSON data itself is too deep to parse? Therefore would I need to create a new property Data inside my object that contains a list of Messages?
Related
I'm following along this tutorial to create a Web API using C#, and I have across an issue. The GET handler is working fine but the POST handler seems to be having issues parsing the body. Whenever I make a GET request, I get a valid response back (photos below), but if I try a POST of PUT, I get a 415 HTTP error.
This is my model:
public class Pet
{
public long Id { get; set; }
public string? Name {get; set;}
public string? Type {get; set;}
public string? Breed {get; set;}
public string? Description {get; set;}
public string? BirthDate {get; set;}
public string? ImageUrl {get; set;}
public long? Adopter {get; set;} = null;
public bool Available {get; set;} = false;
}
This is the corresponding controller:
public class PetsController : ControllerBase {
...
// The handler for POST
[HttpPost]
public async Task<ActionResult<Pet>> PostPet([FromBody]Pet pet)
{
_context.Pet.Add(pet);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetPet), new { id = pet.Id }, pet);
}
...
}
Here is a GET request response.
And here is a POST request response.
This is the payload I'm sending.
Complete JSON response (for POST).
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-298784fa1ee54a98afe19a0db7410d23-6cef112f5fc292b1-00",
"errors":{
"$":[
"'-' is invalid within a number, immediately after a sign character ('+' or '-'). Expected a digit ('0'-'9'). Path: $ | LineNumber: 0 | BytePositionInLine: 1."
],
"pet":[
"The pet field is required."
]
}
}
Two ways to resolve this:
Change [FromBody] to [FromForm] in your controllers method signature:
Or, don't use a form, and instead use a POST body in JSON.
For example:
{
"name": "allan",
"type": "cat",
"breed": "husky",
"description": "a nice doggy",
"birthDate": "12/12/2009",
"imageUrl": "dog.png"
}
This should bind the values properly:
I need to inject the specific property value to object that is being deserialize using JsonConvert.DeserializeObject method.
for example I have a class
public class Employee
{
public int EmployeeID {get; set;}
public string Name {get; set;}
public int OrgnizationID {get; set;}
}
Json
[
{
"employeeID": 1,
"name": "Neeraj"
},
{
"employeeID": 2,
"name": "Sam"
},
{
"employeeID": 3,
"name": "Jonson"
}
]
above json string converting to list of employee. Here I am looking a way to set the OrgnizationID with some value for full of list. I know I can set it after conversion, but god to have if I can set it along with conversion.
var employees = JsonConvert.DeserializeObject<List<Employee>>(jsonData);
in above line of code I am also passing the JsonSerializerSettings for some other purpose that not defined here just to keep question simple.
I have an web API function that has a property that can take different shapes. Actually i need to save a json in database.
I will give you some examples
post body
{
"title":"example 1",
"type": "0",
"extraData": { "name": "bob",
// here is the catch this is first type of object let's say children
[{
"age": 10
"toys": "bear, goat"
},
{
"age": 18
"toys": "guitar"
}]
}
}
{
"title":"example 1",
"type": "1",
"extraData": { "name": "john",
// here is the catch this is first type of object let's say grandparents
[{
"age": 90
"cars": "honda civic"
},
{
"age": 18
"car": "renault megan, pegeout 206"
}]
}
}
Now let's assume that we can't merge grandparents and children together in a class so my classes will look something like:
public class Family{
public string Title {get; set;}
public string ExtraData {get; set;}
public int Type {get;set;}
}
public class ExtraData<T> where T: Person{
public string Name{get;set;}
public List<T> Persons {get;set;}
}
public class Person{
public int Age {get;set;}
}
public class Child : Person{
public string Toys{get;set;}
}
public class Grandparent : Person{
public string Cars{get;set;}
}
In the api method I was thinking to do something like:
public void Save(Family model)
{
// to parse extraData my idea was to
switch(mode.Type)
{
case 0: var childrens = JsonConvert.DeserializeObject<ExtraData<Child>>(model.ExtraData);
// do stuff
break;
case 1: var grandparents = JsonConvert.DeserializeObject<ExtraData<Child>>(model.ExtraData);
// do stuff
break;
}
// save the object
}
The issue is that on the api call I get nothing in the extraData string. And I can't put in Family something like
public ExtraData<Person> Persons {get;set;}
because it will deserialize to the base type and I will lose the subclass information.
I know is to do something like json stringify but I would like this to be my last resort. Also i have tried to use dynamic instead of Family but I still need to deserialze it and having same issue.
What is the best approach here?
I would like to ask somebody, how to correct prepare collection of classes to binding values from [FromBody].
I have three classes:
public class Point
{
public int? X {get; set;}
}
public class CollectionPoint
{
public List<Point> Point {get; set;}
}
public class TestBlock
{
public string? Name {get; set;}
public List<CollectionPoint> CollectionPoint {get; set;}
}
Than I have methods for reading JSON object, like:
public string Post([FromBody] TestBlock testBlock)
Finally, I have testing JSON,like:
{
"Name":"Block1",
"CollectionPoint":
[
{
"Point":{"X":"20"},
"Point":{"X":"22"},
"Point":{"X":"25"}
},
{
"Point":{"X":"40"}
}
]
}
But problem is, that this solution doesnt work. Can someone help me? Thank you.
The question is not very clear.
Do you want a collection of Points ?
If so there is an extra class somwhere.
public class Point
{
public int? X {get; set;}
}
public class TestBlock
{
public string? Name {get; set;}
public List<Point> CollectionPoint {get; set;}
}
Do you want a collection of a collection of points?
If so the json is malformed, it should be:
{
"Name":"Block1",
"CollectionPoint":
[
{
"Point":
[
{"X":"20"},
{"X":"22"},
{"X":"25"}
]
},
{
"Point":
[
{"X":"20"}
]
}
]
}
How can we hide the C# property where serializing with JSON.NET library. Suppose, we have class Customer
public class Customer
{
public int CustId {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public bool isLocked {get; set;}
public Customer() {}
}
public class Test
{
Customer cust = new Customer();
cust.CustId = 101;
cust.FirstName = "John"
cust.LastName = "Murphy"
string Json = JsonConvert.SerializeObject(cust);
}
JSON
{
"CustId": 101,
"FirstName": "John",
"LastName": "Murphy",
"isLocked": false
}
This object is converted to json, but i didn't specify the isLocked property. As library will serialize the entire class, is there any way to ignore a property during json serialization process or if we can add any attribute on the property.
EDIT:
Also, If we create two instance of Customer class in an array. if we didn't specify is locked property on the second instance, can we can property hide for second object.
JSON
{
"Customer": [
{
"CustId": 101,
"FirstName": "John",
"LastName": "Murphy",
"isLocked": false
},
{
"CustId": 102,
"FirstName": "Sara",
"LastName": "connie"
}
]
}
Use the JSON.Net attributes:
public class Customer
{
public int CustId {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
[JsonIgnore]
public bool isLocked {get; set;}
public Customer() {}
}
For more information: https://www.newtonsoft.com/json/help/html/SerializationAttributes.htm
Yes, marking your properties with JsonIgnore is probably best.
However, if you do want to chose at runtime, add a public bool ShouldSerialize{MemberName} to your class. When JSON.net Serialises it will call it, and if false, not serialise. isLocked is false by default, perhaps you do want to serialise it when its true, for example.
Mark that property with the JsonIgnore attribute.