How to parse JSON child nodes as an array using json.net? [duplicate] - json.net

I am trying to make use of the API for a well known online meeting provider. One of their API calls returns an object that looks like this.
{
"5234592":{
"pollsAndSurveys":{
"questionsAsked":1,
"surveyCount":0,
"percentageSurveysCompleted":0,
"percentagePollsCompleted":100,
"pollCount":2},
"attendance":{
"averageAttendanceTimeSeconds":253,
"averageInterestRating":0,
"averageAttentiveness":0,
"registrantCount":1,
"percentageAttendance":100}
},
"5235291":{
"pollsAndSurveys":{
"questionsAsked":2,
"surveyCount":0,
"percentageSurveysCompleted":0,
"percentagePollsCompleted":0,
"pollCount":0},
"attendance":{
"averageAttendanceTimeSeconds":83,
"averageInterestRating":0,
"averageAttentiveness":0,
"registrantCount":1,
"percentageAttendance":100}
}
}
I am trying to make a strongly typed object in C# so I can deal with this data. I can create objects for the pollsAndSurveys bit and the attendance bit but I don't know how to deal with the id number, in this case 5234592 & 5235291, that is the identifier for the session.
public class AttendanceStatistics
{
[JsonProperty(PropertyName = "registrantCount")]
public int RegistrantCount { get; set; }
[JsonProperty(PropertyName = "percentageAttendance")]
public float PercentageAttendance{ get; set; }
[JsonProperty(PropertyName = "averageInterestRating")]
public float AverageInterestRating { get; set; }
[JsonProperty(PropertyName = "averageAttentiveness")]
public float AverageAttentiveness { get; set; }
[JsonProperty(PropertyName = "averageAttendanceTimeSeconds")]
public float AverageAttendanceTimeSeconds { get; set; }
}
public class PollsAndSurveysStatistics
{
[JsonProperty(PropertyName = "pollCount")]
public int PollCount { get; set; }
[JsonProperty(PropertyName = "surveyCount")]
public float SurveyCount { get; set; }
[JsonProperty(PropertyName = "questionsAsked")]
public int QuestionsAsked { get; set; }
[JsonProperty(PropertyName = "percentagePollsCompleted")]
public float PercentagePollsCompleted { get; set; }
[JsonProperty(PropertyName = "percentageSurveysCompleted")]
public float PercentageSurveysCompleted { get; set; }
}
public class SessionPerformanceStats
{
[JsonProperty(PropertyName = "attendance")]
public AttendanceStatistics Attendance { get; set; }
[JsonProperty(PropertyName = "pollsAndSurveys")]
public PollsAndSurveysStatistics PollsAndSurveys { get; set; }
}
public class WebinarPerformanceStats
{
public List<SessionPerformanceStats> Stats { get; set; }
}
I am pretty sure that the WebinarPerformanceStats is the issue but I don't know where to go from here. What would I have to change to get
NewtonSoft.Json.JsonConvert.DeserializeObject<WebinarPerformanceStats>(theJsonResponse)
to work?

Make your root object be a dictionary:
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, SessionPerformanceStats>>(theJsonResponse);
Json.NET serializes a dictionary from and to a JSON object, with the keys being converted to the property names. In your case, the ID numbers will be deserialized as the dictionary keys. If you are sure they will always be numbers, you could declare them as such:
var dictionary = JsonConvert.DeserializeObject<Dictionary<long, SessionPerformanceStats>>(theJsonResponse);
See Serialize a Dictionary and Deserialize a Dictionary

Related

Best way to parse a Gremlin.Net response?

What is the best way to get POCO's from a Gremlin.Net response?
Right now I manually cast to dictionaries:
var results = await gremlinClient.SubmitAsync<Dictionary<string, object>>("g.V()");
var result = results[0];
var properties = (Dictionary<string, object>)result["properties"];
var value = ((Dictionary<string, object>)properties["myValue"].Single())["value"];
I found that the GremlinClient can only return dynamic objects, if you put anything else as the type, it fails (unless I was just doing something wrong).
What I ended up doing was serialising the dynamic object to JSON and then deserialising it back to the object type I wanted:
var results = await gremlinClient.SubmitAsync<dynamic>("g.V()");
JsonConvert.DeserializeObject<MyResult>(JsonConvert.SerializeObject(results));
The dynamic object is just a Dictionary, but if you serialise it first it has the proper hierarchy of fields/properties which can then be deserialised to what you actually expect.
Seems a bit of a pain to have to do the extra conversion, but only way I got it to work.
You can get your properties by using MyClass similar to
class ProviderProperties {
public object Name { get; set; }
public object contact { get; set; }
public object requesttype { get; set; }
public object address { get; set; }
public object phone { get; set; }
public object description { get; set; }
public object otherState { get; set; }
public object otherCity { get; set; }
public object addressStreet { get; set; }
}
class MyClass {
public string id { get; set; }
public string label { get; set; }
public string type { get; set; }
public ProviderProperties properties { get; set; }
}
and using it in
JsonConvert.DeserializeObject<MyClass>(JsonConvert.SerializeObject(results));
Try this approach
IGremlinClient janusClient = JanusGraphClientBuilder.BuildClientForServer(new GremlinServer("localhost", 8182)).Create();
GraphTraversalSource g = Traversal().WithRemote(new DriverRemoteConnection(janusClient));
IList<Vertex> x = g.V().HasLabel("YourLabel").Has("YourpPopertyName", "some value").ToList();

DocumentDB LAMBDA SqlMethod.Like and .Contains NotImplemented Exception

Im trying to do a simple "LIKE" query using a LAMBDA expression using CreateDocumentQuery; however after trying .Contains and SqlMethod.Like and both times receiving the response NotImplementedException I don't know what to try next!
Update: As of 5/6/15, DocumentDB added a set of String functions including STARTSWITH, ENDSWITH, and CONTAINS. Please note that most of these functions do not run on the index and will force a scan.
LIKE and CONTAINS are not yet supported in DocumentDB.
You'll want to check out the DocumentDB feedback page and vote on features (e.g. LIKE and CONTAINS) to get your voice heard!
Because I only needed to search against a discreet subset of properties of the larger object I implemented a .Contains search function as below. It works as expected though I have no idea regarding performance or scalability.
Domain Models
public interface ITaxonomySearchable
{
string Name { get; set; }
string Description { get; set; }
}
public class TaxonomySearchInfo : ITaxonomySearchable {
[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
}
public class TaxonomyContainer : ITaxonomySearchable
{
[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }
[JsonProperty(PropertyName = "userId")]
public string UserId { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
[JsonProperty(PropertyName = "tags")]
public string[] Tags { get; set; }
[JsonProperty(PropertyName = "taxonomy")]
public Node[] Taxonomy { get; set; }
}
Search method
public async static Task<List<TaxonomySearchInfo>> Search(string searchTerm)
{
var db = GetJsonDocumentDb.GetDb();
using (var client = GetJsonDocumentDb.GetClient())
{
var documentCollection = await GetJsonDocumentDb.GetDocumentCollection(db, client, "TaxonomyContainerCollection");
return client.CreateDocumentQuery<TaxonomySearchInfo>(documentCollection.DocumentsLink)
.AsEnumerable()
.Where(r => r.Name.Contains(searchTerm) || r.Description.Contains(searchTerm))
.ToList();
}
}

AutoMpper + Map Complex Nested Many to Many Relationship

I have domain model like this
public class EntityOne
{
public int EnityOneId { get; set; }
public int EntityOnePropertyOne { get; set; }
public List<EntityTwo> EntityTwos { get; set; }
}
public class EntityTwo
{
public int EntityTwoId { get; set; }
public string EntityTwoPropertyOne { get; set; }
public int EntityThreeId { get; set; }
public int EnityOneId { get; set; }
public virtual EntityOne EntityOne { get; set; }
public virtual EntityThree EntityThree { get; set; }
}
public class EntityThree
{
public int EntityThreeId { get; set; }
public string EntityThreePropertyOne { get; set; }
}
and I have DTO like this
public class EntityDTO
{
public int EntityOnePropertyOne { get; set; }
public string EntityThreePropertyOne_ValueOne { get; set; }
public string EntityThreePropertyOne_ValueTwo { get; set; }
public string EntityThreePropertyOne_ValueThree { get; set; }
public string EntityThreePropertyOne_ValueFour { get; set; }
public string EntityThreePropertyOne_ValueFive { get; set; }
}
I want to configure mapping from DTO to DomainModel and the reverse using AutoMapper but I didnt know how to do that... any suggestion or help
I'm not sure what you're trying to accomplish here.
I get that you want to map to EntityDTO, but from what other type? I will assume you want to use EntityTwo as the source.
In that case,
EntityOnePropertyOne: Will be obtained automatically via Flattening from the source (EntityTwo) - So, no problem here.
EntityThreePropertyOne_ValueOne: This will assume you have a property called EntityThree (which you do), and within that type, a property called PropertyOne_ValueOne of type int (which you don't). Same applies for the rest.
The other way around will get trickier, since I see there will be lots of properties ignored, so you need to tell AutoMapper, that you don't want it to be concerned about all that bunch of properties in your complex type, that don't come from the DTO.

Asp Mvc model binding of array with content type application/x-www-form-urlencoded

Below is a POST url with content type application/x-www-form-urlencoded
POST
http://partner-site.com/api_implementation/hotel_availability
BODY
api_version=4
&hotels=[{"ta_id":97497,"partner_id":"229547","partner_url":"http://partner.com/deeplink/to/229547"},{"ta_id":97832,"partner_id":"id34234","partner_url":"http://partner.com/deeplink/to/id34234"}]
&start_date=2013-07-01
&end_date=2013-07-03
&num_adults=2
&num_rooms=1
&lang=en_US
&currency=USD
&user_country=US
&device_type=d
&query_key=6167a22d1f87d2028bf60a8e5e27afa7_191_1360299600000_2_2
CONTENT TYPE
application/x-www-form-urlencoded
And i have wrote the class that read like
public class HotelAvailabilityRequest
{
public int api_version { get; set; }
public List<HotelSummary> hotels { get; set; }
public string start_date { get; set; }
public string end_date { get; set; }
public int num_adults { get; set; }
public int num_rooms { get; set; }
public string lang { get; set; }
public string query_key { get; set; }
public string currency { get; set; }
public string user_country { get; set; }
public string device_type { get; set; }
}
public class HotelSummary
{
public int ta_id { get; set; }
public string partner_id { get; set; }
public string partner_url { get; set; }
}
When i use the HotelAvailabilityRequest in my ASP MVC method
public ActionResult Hotel_Availability(HotelAvailabilityRequest request)
{}
I'm getting other parameter like request.api_version, request.device_type except request.hotels
I'm getting request.hotels.Count() equal to zero.
How do i get the request.hotel to bind accordingly?
After a few round of testing, I resort to manually parsing and deserializing my query string. Since primitive types (int, string like request.api_version) are well captured by the default model binder, my focus is to resolve the complex object type (request.hotels) that is problem.
First, I get the full query string with
Request.InputStream.Position = 0;
var queryString = new StreamReader(Request.InputStream).ReadToEnd();
var queryStringCollection = HttpUtility.ParseQueryString(queryString);
Then, I deserialize the query string into the intended object list
var hotelStr = queryStringCollection.Get("hotels");
var requestHotels = (List<HotelSummary>) JsonConvert.DeserializeObject(hotelStr, typeof (List<HotelSummary>));
request.hotels = requestHotels;
Not the best solution but it works. Hope someone workout a better ModelBinder for ASP MVC that resolve complex object type at binding.

getting json byte array in list

I got null value for byte array in json web service when deserializing.but it returns byte array when invoked from browser.
C# Code:
var url = re.DownloadString("XXXX/ListService.svc/lstFooddtl/1/21");
var a = JsonConvert.DeserializeObject<FooddtlResult>(url);
In a i got null for food_photo...when i deserialize...
c# Class:
public class photo
{
public byte[] food_photo { get; set; }
}
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public photo[] food_photo { get; set; }
public string unitcost { get; set; }
}
public class FooddtlResult
{
public Food[] Result { get; set; }
}
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[255,216,255,224,0,....217],"unitcost":null}]}
Your model does not match the JSON. For correct deserialization change your Food class to
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public byte[] food_photo { get; set; }
public string unitcost { get; set; }
}
and remove the photo class.
Otherwise, if you want to keep the model structure, then correct JSON should be:
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[{"food_photo":[255,216,255,224,0,....217]},{"food_photo":[255,...]},...],"unitcost":null}]}

Resources