Invalid class property declaration for json mapping - c#

I have below json received from mailgun API.
{
"items": [{
"delivery-status": {
"message": null,
"code": 605,
"description": "Not delivering to previously bounced address",
"session-seconds": 0
},
"event": "failed",
"log-level": "error",
"recipient": "test#test.com"
},
{
//some other properties of above types
}]
}
Now I was trying to create a class structure for above json to auto-map the properties after deserializing.
public class test
{
public List<Item> items { get; set; }
}
public class Item
{
public string recipient { get; set; }
public string #event { get; set; }
public DeliveryStatus delivery_status { get; set; }
}
public class DeliveryStatus
{
public string description { get; set; }
}
This is how I deserialize and try to map the properties.
var resp = client.Execute(request);
var json = new JavaScriptSerializer();
var content = json.Deserialize<Dictionary<string, object>>(resp.Content);
test testContent = (test)json.Deserialize(resp.Content, typeof(test));
var eventType = testContent.items[0].#event;
var desc = testContent.items[0].delivery_status.description; //stays null
Now in the above class Item, recipient and #event gets mapped properly and since it was a keyword I was suppose to use preceding # character and it works well. But the delivery-status property from json, does not get mapped with delevery_status property in class DeliveryStatus. I have tried creating it as deliveryStatus or #deliver-status. The earlier on doesn't map again and the later one throws compile time exception. Is there anyway these things can be handled, like declaring a property with - in between? I cannot change response json as it is not getting generated from my end. Hoping for some help.
Update
Changed the class as below referring this answer, but did not help. Its null again.
public class Item
{
public string #event { get; set; }
[JsonProperty(PropertyName = "delivery-status")]
public DeliveryStatus deliveryStatus { get; set; }
}

I am not sure what the issue is at your end, but at least it works if you use this code. Make sure to include a recent version of Newtonsoft.Json in your project and you should be fine.
public class DeliveryStatus
{
public object message { get; set; }
public int code { get; set; }
public string description { get; set; }
[JsonProperty("session-seconds")]
public int session_seconds { get; set; }
}
public class Item
{
[JsonProperty("delivery-status")]
public DeliveryStatus delivery_status { get; set; }
public string #event { get; set; }
[JsonProperty("log-level")]
public string log_level { get; set; }
public string recipient { get; set; }
}
public class RootObject
{
public List<Item> items { get; set; }
}
public static void Main(string[] args)
{
string json = #"{
""items"": [{
""delivery-status"": {
""message"": null,
""code"": 605,
""description"": ""Not delivering to previously bounced address"",
""session-seconds"": 0
},
""event"": ""failed"",
""log-level"": ""error"",
""recipient"": ""test#test.com""
}]
}";
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
}

Related

Deserialize JSON using specific properties

I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());

C# Entity Framework Json deserialize String array issues

I have A Json file Which can be used for deserialize to Entity framework. For simplify we can assume the Json like this
{
"stat": "val0",
"results": [
{
"datasets": [
"val1",
"val2"
],
"head": "val3"
},
{
"datasets": [
"val4",
"val5"
],
"head": "val6"
}
]
}
And my Entity Classes like
[Serializable]
public class Root
{
[Key]
public int Id { get; set; }
public int stat { get; set; }
public List<Result> results { get; set; }
}
[Serializable]
public class Result
{
[Key]
public int Id { get; set; }
public List<String> _strings { get; set; }
public List<string> Strings
{
get { return _strings; }
set { _strings = value; }
}
[Required]
public string datasets
{
get { return String.Join(",", _strings); }
set { _strings = value.Split(',').ToList(); }
}
public string head{ get; set; }
public virtual root { get; set; }
}
I know Entity Framework does not support primitive types and I know problem causes from my datasets fields. that I found this way to solve String array deserialize issue here. I have tried
URL = "http://...";//Restful webservice address
WebClient client = new WebClient();
String JSON= client.DownloadString(URL);
var dsobj = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(json);
But I got
System.InvalidOperationException
Then I have decided to use Newtonsoft
URL = "http://...";//Restful webservice address
WebClient client = new WebClient();
String JSON= client.DownloadString(URL);
var dsobj = JsonConvert.DeserializeObject<Root>(json);
Then I got this error
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: [. Path 'results[0].senses[0].definition', line 1, position...
I found this but I cant figure it out.
How can Fix these isseus. Any help appreciated.
Your json consist of two unwanted commas, try removing those
try
[Serializable]
public class Root
{
[Key]
public int Id { get; set; }
public string stat { get; set; } // changed to a string
public List<Result> results { get; set; }
}
[Serializable]
public class Result
{
[Key]
public int Id { get; set; }
public List<String> _dataSets { get; set; }
public List<string> dataSets // the JSON array will deserialize into this property
{
get { return _dataSets; }
set { _dataSets = value; }
}
[Required]
public string DatasetsAsString
{
get { return String.Join(",", _dataSets); }
set { _dataSets = value.Split(',').ToList(); }
}
public string head{ get; set; }
public virtual root { get; set; }
}
Edit: stat property has to be a string too.

Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {“name”:“value”})

I have JSON returning in the following format:
{
"Items": [
{
"unique_id": "11111111111",
"rages": {
"rage_content": "Hello rage 2",
"date_stamp": "21/07/2017",
"id": 2
}
},
{
"unique_id": "2222222222",
"rages": {
"rage_content": "Hello rage 1",
"date_stamp": "21/07/2017",
"id": 1
}
}
],
"Count": 2,
"ScannedCount": 2
}
And I have the following 2 classes defined:
Items.cs:
namespace ragevent_A0._0._1
{
class Items
{
public String rage_id { get; set; }
public rage rage { get; set; }
}
}
rage.cs:
class rage
{
public String rage_content { get; set; }
public String date_stamp { get; set; }
public int id { get; set; }
}
I am using the following code in order to attempt to deseralize the JSON returned above:
List<Items> data = JsonConvert.DeserializeObject<List<Items>>(json);
However, I am not able to successfully deserialize the data due to the above error. I have tried a few solutions online, however I have not managed to find a solution which works with the format of my returned JSON. I have used a JSON formatter and it is formatted correctly, so that shouldn't be the issue.
Any help would be much appreciated!
For the posted JSON data below should be the model you need (credit: http://json2csharp.com/). There is mismatch between the property name rage_id. You can use JsonProperty attribute
public class Rages
{
public string rage_content { get; set; }
public string date_stamp { get; set; }
public int id { get; set; }
}
public class Item
{
[JsonProperty(Name="rage_id")]
public string unique_id { get; set; }
public Rages rages { get; set; }
}
public class RootObject
{
public List<Item> Items { get; set; }
public int Count { get; set; }
public int ScannedCount { get; set; }
}
Your deserialization should be
var data = JsonConvert.DeserializeObject<RootObject>(json);

Create a JSON string in C#

I'm trying to create an object to be returned as JSON for my REST Web Service.
I wish to get something returned like this:
{
"message": [
{
"name": "whatever.bmp"
}
],
"errors": null,
"FileInflected": 0,
"path": "C:\thepath"
}
So, how can I change the class (eFileOutput) in C#?
How can I change the class I have below?
Currently I'm able to create similar output like this:
{
"message": "Hello World",
"errors": null,
"FileInfected": 0,
"path": "C:\bla bla..."
}
and my C# class is as follows:
[DataContract]
public class eFileOutput
{
[DataMember]
public string message { get; set; }
[DataMember]
public string errors { get; set; }
[DataMember]
public Int32 FileInfected { get; set; }
[DataMember]
public string path { get; set; }
}
Tks
This is the classes that represent the JSON you've stated:
public class Message
{
public string name { get; set; }
}
public class MyObject
{
public List<Message> message { get; set; }
public object errors { get; set; }
public int FileInflected { get; set; }
public string path { get; set; }
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new MyObject
{
message = new List<Message>
{
new Message {name = "whatever.bmp"}
},
FileInflected = 0,
path = #"c:\thepath"
});
Edit (thanks to devzero): Then you can serialize using Newtonsoft (my favorite) or JavaScriptSerializer as stated here: Turn C# object into a JSON string in .NET 4
public class MyObject
{
public Message Message { get; set; }
public List<Error> Errors { get; set; }
public int FileInflected { get; set; }
public string Path { get; set; }
}
public class Message
{
public string Name { get; set; }
}
public class Error
{
//Whatever you want
}
and if You want to serialize member as camelCase, describe like this:
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var json = JsonConvert.SerializeObject(c, jsonSerializerSettings);

Deserialize JSON with Json.NET in Windows 8 Store App (C#)

i'm trying to program a Windows Runtime Component in C# in Visual Studio 2012 for Windows 8.
I have some issues by using Json.NET to deserialize a JSON like this:
{
"header": {
"id": 0,
"code": 0,
"hits": 10
},
"body": {
"datalist": [
{
"name": "",
"city": "",
"age": 0
},
{
"name": "",
"city": "",
"age": 0
},
{
"name": "",
"city": "",
"age": 0
}
]
}
}
My intention is to get a top-level Dictionary out of this and to interpret every value as a string. For this example you would get a dictionary with two keys (header and body) and the matching values as strings. After this you could go down the tree.
A function like this
Dictionary<string, string> jsonDict =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
would be nice, but this one only accept string-values.
Do anybody knows how to ignore the types or get it on another way?
Furthermore to get out of the body-value "{"datalist": [ { "name": "", ....}]}" a list of dictionaries.
Thanks in advance!
I would use this site and deserialize as
var myObj =JsonConvert.DeserializeObject<RootObject>(json);
public class Header
{
public int id { get; set; }
public int code { get; set; }
public int hits { get; set; }
}
public class Datalist
{
public string name { get; set; }
public string city { get; set; }
public int age { get; set; }
}
public class Body
{
public List<Datalist> datalist { get; set; }
}
public class RootObject
{
public Header header { get; set; }
public Body body { get; set; }
}
You can also use dynamic keyword without declaring any classes
dynamic myObj =JsonConvert.DeserializeObject(json);
var age = myObj.body.datalist[1].age;
And since JObject implements IDictionary<> this is also possible
var jsonDict = JObject.Parse(json);
var age = jsonDict["body"]["datalist"][1]["age"];
If you're having a problem defining your classes, a nice feature in VS 2012 allows you to generate classes to hold your JSON/XML data using the Paste Special command under Edit. For instance, your JSON created this class:
public class Rootobject
{
public Header header { get; set; }
public Body body { get; set; }
}
public class Header
{
public int id { get; set; }
public int code { get; set; }
public int hits { get; set; }
}
public class Body
{
public Datalist[] datalist { get; set; }
}
public class Datalist
{
public string name { get; set; }
public string city { get; set; }
public int age { get; set; }
}
...which you could then deserialize your request into the type of RootObject, e.g.
var obj = JsonConvert.DeserializeObject<RootObject>(json);

Categories

Resources