C# deserializator doesn't return result - c#

i have problem with my deserialization and don't know how to deal.
var jsonString = #"
{
""Result"": [
{
""Id"": 994,
""Name"": ""LL Bottom Bracket"",
},
{
""Id"": 995,
""Name"": ""ML Bottom Bracket"",
}
]
}";
HotelRoomDTO class looks like:
public class HotelRoomDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
And Service is
public async Task<IEnumerable<HotelRoomDTO>> GetHotelRooms(string checkInDate, string checkOutDate)
{
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var response = await _client.GetAsync($"api/hotelroom?checkInDate={checkInDate}& checkOutDate={checkOutDate}");
var content = await response.Content.ReadAsStringAsync();
var rooms = JsonConvert.DeserializeObject<IEnumerable<HotelRoomDTO>>(content, settings);
return rooms;
}
When i try to run app deserializator crash and doesnt return result. I think that problem is in this "Result" list of objects.When it doesnt exist everithing works fine but when i get data from real Db and try to deserialize it automatic adds this "Result" and code doesnt work

You can try a creting a Root class:
public class Root
{
[JsonProperty("Result")]
public List<HotelRoomDTO> Result { get; set; }
}
And deserialize him:
var rooms = JsonConvert.DeserializeObject<Root>(jsonString, settings);

Your problem is that you are receiving a list of "HotelRoomDTOs", but your model is only made for one.
Diego's answer would work on this occasion. What you want to do is the following. Change your model file to the following:
public class Result
{
public int Id { get; set; }
public string Name { get; set; }
}
public class HotelRoomDTO
{
public List<Result> Result { get; set; }
}
In your GetHotelRooms function you now change
var rooms = JsonConvert.DeserializeObject<IEnumerable<HotelRoomDTO>>(content, settings);
to
var rooms = JsonConvert.DeserializeObject<HotelRoomDTO>(content, settings);
The variable rooms is now a list filled with HotelRoomDTOs.

I found simplest solution i removed "Result" because i dont need it and after that desialize.Thank you for another answers.
var result = JObject.Parse(content)["Result"].ToString(Formatting.None);
var rooms = JsonConvert.DeserializeObject<IEnumerable<HotelRoomDTO>>(content);

Related

Load JSON object into array?

I'm having trouble loading this json object into an array.
Here is a snippet (fragment) of my JSON response from the API:
{
"count":192,
"value":[
{
"id":"03dd9f56-108f-4e8f-b92e-93df05717464",
"name":"IIBTest",
"url":"https://devops.com/tfs/DefaultCollection/_apis/projects/03dd9f56-108f-4e8f-b92e-93df05717464",
"state":"wellFormed",
"revision":14434848,
"visibility":"private",
"lastUpdateTime":"2016-08-19T12:21:37.187Z"
},
{
"id":"b7e15034-fc8f-4f7e-866a-cb06f44b12ed",
"name":"MS Project POC",
"description":"POC for MS Project with TFS",
"url":"https://devops.com/tfs/DefaultCollection/_apis/projects/b7e15034-fc8f-4f7e-866a-cb06f44b12ed",
"state":"wellFormed",
"revision":14434955,
"visibility":"private",
"lastUpdateTime":"2017-10-03T19:31:56.56Z"
},
{
"id":"59e06621-c5f5-4fd1-9c55-1def541b99d9",
"name":"WorkflowReporting",
"url":"https://devops.com/tfs/DefaultCollection/_apis/projects/59e06621-c5f5-4fd1-9c55-1def541b99d9",
"state":"wellFormed",
"revision":14434591,
"visibility":"private",
"lastUpdateTime":"2015-09-11T06:59:12.21Z"
},
{
"id":"78a802f0-5eee-4bcb-bde9-a764e46f56db",
"name":"iSolutions",
"description":"",
"url":"https://devops.com/tfs/DefaultCollection/_apis/projects/78a802f0-5eee-4bcb-bde9-a764e46f56db",
"state":"wellFormed",
"revision":14435476,
"visibility":"private",
"lastUpdateTime":"2021-08-05T17:17:26.193Z"
},
{
"id":"1f20506a-63a5-486a-a857-fec64d7486a6",
"name":"Training",
"description":"MLITS Training and Learning",
"url":"https://devops.com/tfs/DefaultCollection/_apis/projects/1f20506a-63a5-486a-a857-fec64d7486a6",
"state":"wellFormed",
"revision":14435350,
"visibility":"private",
"lastUpdateTime":"2021-04-08T22:48:02.923Z"
},
...
}
And here is my code:
public class Rootobject
{
public int count { get; set; }
public Value[] value { get; set; }
}
public class Value
{
public string id { get; set; }
public string name { get; set; }
public string url { get; set; }
public string state { get; set; }
public int revision { get; set; }
public string visibility { get; set; }
public DateTime lastUpdateTime { get; set; }
public string description { get; set; }
}
static void Main(string[] args)
{
var client = new RestClient("https://devops.americannational.com/tfs/defaultcollection/_apis/projects?$top=300&api-version=5.0")
{
Authenticator = new RestSharp.Authenticators.NtlmAuthenticator()
};
client.Timeout = -1;
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
var jsonString = response.Content;
var jo = JObject.Parse(jsonString);
//...
}
I am wanting to load the names of the projects into the Array so that I can later iterate through them. Any help is appreciated, I have tried a few things but not having much luck.
you can use var jo = JsonConvert.DeserializeObject<Rootobject>(jsonString);
and then iterate through jo.value
try this
var jsonDeserialized= JsonConvert.DeserializeObject<Rootobject>(json);
as example how to use it this query returns array of project names
var projectNames= jsonDeserialized.value.Select(v => v.name ).ToArray();
output
["IIBTest","MS Project POC","WorkflowReporting","iSolutions","Training"]
this returns a list of projects
var projects= jsonDeserialized.value.ToList();

Converting JSON array

I am attempting to use the Newtonsoft JSON library to parse a JSON string dynamically using C#. In the JSON is a named array. I would like to remove the square brackets from this array and then write out the modified JSON.
The JSON now looks like the following. I would like to remove the square bracket from the ProductDescription array.
{
"Product": "123",
"to_Description": [
{
"ProductDescription": "Product 1"
}
]
}
Desired result
{
"Product": "123",
"to_Description":
{
"ProductDescription": "Product 1"
}
}
I believe I can use the code below to parse the JSON. I just need some help with making the modification.
JObject o1 = JObject.Parse(File.ReadAllText(#"output.json"));
The to_Description property starts off as List<Dictionary<string,string>> and you want to take the first element from the List.
So, given 2 classes
public class Source
{
public string Product {get;set;}
public List<Dictionary<string,string>> To_Description{get;set;}
}
public class Destination
{
public string Product {get;set;}
public Dictionary<string,string> To_Description{get;set;}
}
You could do it like this:
var src = JsonConvert.DeserializeObject<Source>(jsonString);
var dest = new Destination
{
Product = src.Product,
To_Description = src.To_Description[0]
};
var newJson = JsonConvert.SerializeObject(dest);
Note: You might want to check there really is just 1 item in the list!
Live example: https://dotnetfiddle.net/vxqumd
You do not need to create classes for this task. You can modify your object like this:
// Load the JSON from a file into a JObject
JObject o1 = JObject.Parse(File.ReadAllText(#"output.json"));
// Get the desired property whose value is to be replaced
var prop = o1.Property("to_Description");
// Replace the property value with the first child JObject of the existing value
prop.Value = prop.Value.Children<JObject>().FirstOrDefault();
// write the changed JSON back to the original file
File.WriteAllText(#"output.json", o1.ToString());
Fiddle: https://dotnetfiddle.net/M83zv3
I have used json2csharp to convert the actual and desired output to classes and manipulated the input json.. this will help in the maintenance in future
First defined the model
public class ToDescription
{
public string ProductDescription { get; set; }
}
public class ActualObject
{
public string Product { get; set; }
public List<ToDescription> to_Description { get; set; }
}
public class ChangedObject
{
public string Product { get; set; }
public ToDescription to_Description { get; set; }
}
Inject the logic
static void Main(string[] args)
{
string json = "{\"Product\": \"123\", \"to_Description\": [ { \"ProductDescription\": \"Product 1\" } ]} ";
ActualObject actualObject = JsonConvert.DeserializeObject<ActualObject>(json);
ChangedObject changedObject = new ChangedObject();
changedObject.Product = actualObject.Product;
changedObject.to_Description = actualObject.to_Description[0];
string formattedjson = JsonConvert.SerializeObject(changedObject);
Console.WriteLine(formattedjson);
}
Why not:
public class EntityDescription
{
public string ProductDescription { get; set; }
}
public class Entity
{
public string Product { get; set; }
}
public class Source : Entity
{
[JsonProperty("to_Description")]
public EntityDescription[] Description { get; set; }
}
public class Target : Entity
{
[JsonProperty("to_Description")]
public EntityDescription Description { get; set; }
}
var raw = File.ReadAllText(#"output.json");
var source = JsonConvert.DeserializeObject<Source>(raw);
var target = new Target { Product = source.Product, Description = source.Description.FirstOrDefault() };
var rawResult = JsonConvert.SerializeObject(target);
Update For dynamic JSON
var jObject = JObject.Parse(File.ReadAllText(#"output.json"));
var newjObject = new JObject();
foreach(var jToken in jObject) {
if(jToken.Value is JArray) {
List<JToken> l = jToken.Value.ToObject<List<JToken>>();
if(l != null && l.Count > 0) {
newjObject.Add(jToken.Key, l.First());
}
} else {
newjObject.Add(jToken.Key, jToken.Value);
}
}
var newTxt = newjObject.ToString();

JSON Not Deserializing

This is one of my first ventures into WCF/JSON. I created a WCF Web Service. This is one of my methods. It is how I serialize the datable to JSON.
public string GetPrayers()
{
DataTable myDt = new DataTable();
myDt = sprocToDT("LoadPrayers");
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
return JSONString;
}
This returns a nice JSON Dataset:
{"GetPrayersResult":"[{\"prayerid\":2,\"prayer\":\"Please pray for my
dog Rusty. He has cancer
:(\",\"prayerCategory\":\"General\",\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayerid\":1,\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerCategory\":\"Sports\",\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]"}
When I go to deserialize it I get all nulls. Here is the classes I created:
public class PrayUpPrayers
{
public string prayer { get; set; }
public string prayerid { get; set; }
public string prayerCategory { get; set; }
public string prayerCategoryID { get; set; }
public string prayerDate { get; set; }
public string handle { get; set; }
public string country { get; set; }
}
public class ThePrayer
{
public PrayUpPrayers prayers { get; set; }
}
}
This is how I am retrieving the JSON:
void getData()
{
var request = HttpWebRequest.Create(string.Format(#"URLGoesHere"));
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
string foo = content.ToString();
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Testing is always null? Is the issue that I am serializing it wrong, could it be the class structure, or is it related to how I am deserializing it. One important note: I checked my JSON on one of these JSONClassesFromC# sites and it only returns the GetPrayersResult as the only class item. Ignoring completely my entire structure.
You didn't provide the code for sprocToDT, but it should create ThePrayer object witch should contain list of PrayUpPrayers
public class ThePrayer
{
public List<PrayUpPrayers> prayers { get; set; }
}
And then you should deserialize ThePrayer object, not PrayUpPrayers.
For example
PrayUpPrayers prayUpPrayers1 = new PrayUpPrayers
{
prayer = "Please pray for my dog Rusty. He has cancer",
prayerid = "2",
prayerCategory = "General",
prayerDate = "2017-06-10T21:24:16.1",
handle = "GuruJee",
country = "USA"
};
PrayUpPrayers prayUpPrayers2 = new PrayUpPrayers
{
prayer = "Help Me I need a appendectomy STAT",
prayerid = "1",
prayerCategory = "Sports",
prayerDate = "2017-04-10T20:30:39.77",
handle = "GuruJee",
country = "USA"
};
ThePrayer thePrayer = new ThePrayer
{
prayers = new List<PrayUpPrayers>
{
prayUpPrayers1, prayUpPrayers2
}
};
myDt in your code should be the same as thePrayer instance in my code.
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
will provide Json that looks like
"{\"prayers\":[{\"prayer\":\"Please pray for my dog Rusty. He has
cancer\",\"prayerid\":\"2\",\"prayerCategory\":\"General\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerid\":\"1\",\"prayerCategory\":\"Sports\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]}"
And deserialize will look like
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.ThePrayer>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
that's simple. you should deserilze the output twice. try this:
var output= DeserializeObject<string>(foo);
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(output,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});

Cycling through Json objects

Fairly new to working with Json and having troubles
[{"page":1,"example":
[{"number":6666666,"Year":2005}]},
{"page":2,"example":
[{"number":555555,"Year":2000}]}]
This is my Json, it's just an example and not actually Json that i'm using but set out the same way
I been using the following c# to get the values within page 1 of the Json but i need help getting the values from page 2 and so forth
var http = new HttpClient();
var response = await http.GetAsync("Example.json");
var result = await response.Content.ReadAsStringAsync();
List<Rootobject> RootList = JsonConvert.DeserializeObject<List<Rootobject>>(result);
foreach (Rootobject item in RootList)
{
listBox1.Items.Add(item.Example[0].number.ToString());
}
Lastly my Classes are
public class Thread
{
[JsonProperty("number")]
public int number { get; set; }
[JsonProperty("year")]
public int year { get; set; }
}
public class Rootobject
{
[JsonProperty("page")]
public int page { get; set; }
[JsonProperty("example")]
public List<Example> example{ get; set; }
}
You can use LINQ expression
var data = var i in RootList
where i.page == 2; // here you can replace the number as per your requirement
Method to return required data
Public Rootobject GetDataByPage(int pageNo) {
return RootList.FirstOrDefault(x => x.page == pageNo);
}

Converting list of objects to json array

I have a List of class objects that have email address and status data members. I am trying to convert these to a json, making sure to have the "operations" word on the array.
This is my class:
class MyClass
{
public string email {get; set; }
public string status { get; set; }
}
This is my current code (not building):
List<MyClass> data = new List<MyClass>();
data = MagicallyGetData();
string json = new {
operations = new {
JsonConvert.SerializeObject(data.Select(s => new {
email_address = s.email,
status = s.status
}))
}
};
This is the JSON I am trying to get:
{
"operations": [
{
"email_address": "email1#email.com",
"status": "good2go"
},
{
"email_address": "email2#email.com",
"status": "good2go"
},...
]
}
EDIT1
I should mention that the data I am getting for this comes from a DB. I am de-serializing a JSON from the DB and using the data in several different ways, so I cannot change the member names of my class.
I believe this will give you what you want. You will have to change your class property names if possible.
Given this class
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
You can add the objects to a list
List<MyClass> data = new List<MyClass>()
{
new MyClass(){email_address = "e1#it.io", status = "s1"}
, new MyClass(){ email_address = "e2#it.io", status = "s1"}
};
Using an anonymous-type you can assign data to the property operations
var json = JsonConvert.SerializeObject(new
{
operations = data
});
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
List<MyClass> data = new List<MyClass>() { new MyClass() { email_address = "email1#email.com", status = "good2go" }, new MyClass() { email_address = "email2#email.com", status = "good2go" } };
//Serialize
var json = JsonConvert.SerializeObject(data);
//Deserialize
var jsonToList = JsonConvert.DeserializeObject<List<MyClass>>(json);
You can try with something like this:
using System.Web.Script.Serialization;
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(data);
Here is the simple code
JArray.FromObject(objList);

Categories