Deserialize multi-part JSON with DataContractJsonSerializer - json

I'm fairly new to the awesomeness that is JSON - I'm using the DataContractJsonSerializer. I cannot get the multiple instances of the Customer objects into the list.
The Attributes work as expected but there are no Customer objects in my List..??
{
"#attributes":
{"count":"2",
"offset":"0",
"limit":"100"
},
"Customer":
{
"firstName":"cust ",
"lastName":"one",
"title":"Owner",
"company":"CustOne Plants",
"companyRegistrationNumber":"",
"vatNumber":"",
"creditAccountID":"1",
"customerTypeID":"4",
"discountID":"0",
"taxCategoryID":"0",
"customerID":"1",
"createTime":"2017-06-19T23:36:11+00:00",
"timeStamp":"2017-06-20T18:55:11+00:00",
"archived":"false"
}
"Customer":
{
"firstName":"cust ",
"lastName":"two",
"title":"Owner",
"company":"CustTwo House of Games",
"companyRegistrationNumber":"",
"vatNumber":"",
"creditAccountID":"1",
"customerTypeID":"4",
"discountID":"0",
"taxCategoryID":"0",
"customerID":"1",
"createTime":"2017-06-19T23:36:11+00:00",
"timeStamp":"2017-06-20T18:55:11+00:00",
"archived":"false"
}
}
.NET code:
StreamReader stream = new StreamReader(#"C:\TMC Projects\PotteryManufacturing\CustomerJSON.txt");
string text = stream.ReadToEnd();
stream.Close();
byte[] byteArray = Encoding.UTF8.GetBytes(text);
MemoryStream stream1 = new MemoryStream(byteArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(CustomersRoot));
var varInfo = serializer.ReadObject(stream1) as CustomersRoot;
stream1.Close();
and finally my classes/data contracts/data members:
[DataContract]
public class CustomersRoot
{
private List<Customer> m_Customers;
public CustomersRoot() { this.Customer = new List<Customer>(); }
[DataMember(Name ="#attributes")]
public Attributes attrs { get; set; }
[DataMember(Name = "Customer")]
public List<Customer> Customer
{
get { return m_Customers; }
set { m_Customers = value; }
}
}
[DataContract]
public class Customer
{
[DataMember(Name ="firstName")]
public string firstName { get; set; }
[DataMember(Name = "lastName")]
public string lastName { get; set; }
[DataMember(Name = "title")]
public string title { get; set; }
[DataMember(Name = "company")]
public string company { get; set; }
[DataMember(Name = "companyRegistrationNumber")]
public string companyRegistrationNumber { get; set; }
[DataMember(Name = "vatNumber")]
public string vatNumber { get; set; }
[DataMember(Name = "creditAccountID")]
public int creditAccountID { get; set; }
[DataMember(Name = "customerTypeID")]
public int customerTypeID { get; set; }
[DataMember(Name = "discountID")]
public int discountID { get; set; }
[DataMember(Name = "taxCategoryID")]
public int taxCategoryID { get; set; }
[DataMember(Name = "customerID")]
public int customerID { get; set; }
[DataMember(Name = "createTime")]
public string createTime { get; set; }
[DataMember(Name = "timeStamp")]
public string timeStamp { get; set; }
[DataMember(Name = "archived")]
public bool archived { get; set; }
}
[DataContract]
public class Attributes
{
[DataMember(Name = "count")]
public int count { get; set; }
[DataMember(Name = "offset")]
public int offset { get; set; }
[DataMember(Name = "limit")]
public int limit { get; set; }
}

I figured out what's going on here - the call can sometimes return an array of Customer objects (not formatted correctly above) OR a single instance of the object. When the web service returns a single Customer instance, the List code does not work. I will have to check on how to deal w/ this issue.

Related

Deserialize OneNote Notebooks API Response

I'm getting an empty object when I try to Deserialize a OneNote GetAllNotebooks query.
string[] tempCapture = null;
var url = new Uri("https://graph.microsoft.com/v1.0/me/onenote/notebooks");
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (IsAuthenticated)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
}
var response = await client.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
tbResponse.Text = result.ToString();
DataContractJsonSerializer ser1 = new DataContractJsonSerializer(typeof(List<Value>));
MemoryStream stream1 = new MemoryStream(Encoding.UTF8.GetBytes(tbResponse.Text.ToString()));
var obj1 = (List<Value>)ser1.ReadObject(stream1);
I'm trying to get a list of notebooks, names, links to add to a database. And my table structure matches the class below.
Here is my OneNote API class
public class Value
{
public bool isDefault { get; set; }
public string userRole { get; set; }
public bool isShared { get; set; }
public string sectionsUrl { get; set; }
public string sectionGroupsUrl { get; set; }
public Links links { get; set; }
public string name { get; set; }
public string self { get; set; }
public string createdBy { get; set; }
public string lastModifiedBy { get; set; }
public string lastModifiedTime { get; set; }
public string id { get; set; }
public string createdTime { get; set; }
}
Here is my new code with the RootObject. I'm still getting an error. It is in the catch exception.
var test = await client.GetAsync(url);
string testStr = await test.Content.ReadAsStringAsync();
DataContractJsonSerializer serial = new DataContractJsonSerializer(typeof(RootObject));
MemoryStream testStream = new MemoryStream(Encoding.UTF8.GetBytes(testStr));
try
{
var objx = (List<RootObject>)serial.ReadObject(testStream);
}
catch(Exception ex)
{
ex.ToString();
//"There was an error deserializing the object of type OneNoteSOAP2.RootObject. End element 'createdBy' from namespace '' expected. Found element 'user' from namespace ''."
}
You can use http://json2csharp.com/. Basically, just copy the value of our JSON being returned, and use the classes generated by this website. Use RootObject to deserialize.
I ran this for you and obtained these classes:
public class OneNoteClientUrl
{
public string href { get; set; }
}
public class OneNoteWebUrl
{
public string href { get; set; }
}
public class Links
{
public OneNoteClientUrl oneNoteClientUrl { get; set; }
public OneNoteWebUrl oneNoteWebUrl { get; set; }
}
public class Value
{
public string id { get; set; }
public string self { get; set; }
public string createdTime { get; set; }
public string name { get; set; }
public string createdBy { get; set; }
public string lastModifiedBy { get; set; }
public string lastModifiedTime { get; set; }
public bool isDefault { get; set; }
public string userRole { get; set; }
public bool isShared { get; set; }
public string sectionsUrl { get; set; }
public string sectionGroupsUrl { get; set; }
public Links links { get; set; }
}
public class RootObject
{
public List<Value> value { get; set; }
}

Newtonsoft Json is not serializing class

I have the following classes that I'm using to collect data and then return the structure in Json.
public class Outcome {
public int id { get; set; }
public string outcome { get; set; }
public string actionStep { get; set; }
public List<OutcomeActionResult> actionResults { get; set; }
public void setData(SqlDataReader reader, DateData dateData) {
this.id = Convert.ToInt32(reader["id"]);
this.outcome = Convert.ToString(reader["outcome"]);
this.actionStep = Convert.ToString(reader["action_step"]);
this.actionResults = new Outcomes().getActionResultByOutcomeId(this.id, dateData);
}
}
public class OutcomeActionResult {
public int id { get; set; }
public string actionResult { get; set; }
public ActionResultQuestion question { get; set; }
public void setData(SqlDataReader reader, DateData dateData) {
this.id = Convert.ToInt32(reader["id"]);
this.actionResult = Convert.ToString(reader["action_result"]);
this.question = new Outcomes().getActionResultQuestionByActionResultId(this.id, dateData);
}
}
public class ActionResultQuestion {
public int id { get; set; }
public string question { get; set; }
public bool isMultipleChoice { get; set; }
public List<MultipleChoiceOption> multipleChoiceOptions { get; set; }
ActionResultAnswer answer { get; set; }
public void setData(SqlDataReader reader, DateData dateData) {
this.id = Convert.ToInt32(reader["id"]);
this.question = Convert.ToString(reader["question"]);
this.isMultipleChoice = Convert.ToBoolean(reader["is_multi"]);
this.answer = new Outcomes().getActionResultAnswersByIdAndDate(this.id, dateData.year, dateData.month, dateData.day, dateData.shiftId);
}
}
public class ActionResultAnswer {
public int id { get; set; }
public string notes { get; set; }
public int employeeId { get; set; }
public int selectedAnswer { get; set; }
public string answer { get; set; }
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
public int shiftId { get; set; }
public void setData(SqlDataReader reader) {
this.id = Convert.ToInt32(reader["id"]);
this.notes = Convert.ToString(reader["notes"]);
this.employeeId = Convert.ToInt32(reader["employee_id"]);
this.selectedAnswer = reader.IsDBNull(reader.GetOrdinal("selected_answer")) ? -1 : Convert.ToInt32(reader["selected_answer"]);
this.answer = Convert.ToString(reader["answer"]);
this.year = Convert.ToInt32(reader["year"]);
this.month = Convert.ToInt32(reader["month"]);
this.shiftId = Convert.ToInt32(reader["shift_id"]);
}
}
As you can see, I have Outcome which contains a list of OutcomeActionResults each of which contains an ActionResultQuestion which has an ActionResultAnswer. Something like this:
Outcome -> List(OutcomeActionResult) --> ActionResultQuestion --> ActionResultAnswer
When I step through the code, all the data is being populated correctly and everything is fine. However, when I serialize the object structure to JSON it serializes everything except the ActionResultAnswer. Basically the deepest level of the structure gets chopped off. I've been unable to find anything that tells me why this is happening or how to have it not happen.
Probably ought to put the code that serializes the objects up here:
var response = outcomes.getOutcomesByClientAndDate(clientId, year, month, day, shiftId, dayOfWeek);
var json = JsonConvert.SerializeObject(response);
The answer property in your ActionResultQuestion class is not public. Therefore, it will not be serialized by Json.Net by default.
You can either make the property public...
public ActionResultAnswer answer { get; set; }
or, if you intend that it not be public, you can mark it with a [JsonProperty] attribute to allow the serializer to "see" it:
[JsonProperty]
ActionResultAnswer answer { get; set; }

Parsing Json gMaps Api in windows Phone 8 using Serialization

I Have json file :
Google Maps Api - place Json
I want Parsing Json using System.Runtime.Serialization;
I can create 3 class :
public class Places
{
[DataMember(Name = "geometry")]
public string Geometry
{
get;
set;
}
[DataMember(Name = "location")]
public string Location { get; set; }
[DataMember(Name = "lat")]
public string Latitude { get; set; }
[DataMember(Name = "lng")]
public string Longitude { get; set; }
[DataMember(Name = "icon")]
public string Icon { get; set; }
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "photo")]
public string Photo { get; set; }
[DataMember(Name = "rating")]
public string Rating { get; set; }
[DataMember(Name = "reference")]
public string Reference { get; set; }
[DataMember(Name = "types")]
public string Types { get; set; }
[DataMember(Name = "vicinity")]
public string Vicinity { get; set; }
}
public class AppConstants
{
public static String baseUri = "https://maps.googleapis.com/maps/api/place/search/json?location=";
}
public class PlaceToMap
{
public GeoCoordinate Coordinate { get; set; }
public string Info { get; set; }
}
[DataContract]
public class PlacesList
{
[DataMember(Name ="results")]
public List<Places> PlaceList { get; set; }
}
MainPage.xaml.cs :
private void updateMap(PlacesList googlePlaceApiRespone)
{
int totalRecords = googlePlaceApiRespone.PlaceList.Count();
try
{
ObservableCollection<PlaceToMap> placeToMapObjs = new ObservableCollection<PlaceToMap>();
for (int index = 0; index < totalRecords; index++)
{
placeToMapObjs.Add(new PlaceToMap()
{
Coordinate = new GeoCoordinate(Convert.ToDouble(googlePlaceApiRespone.PlaceList.ElementAt(index).Latitude),
Convert.ToDouble(googlePlaceApiRespone.PlaceList.ElementAt(index).Longitude)),
Info = googlePlaceApiRespone.PlaceList.ElementAt(index).Name + Environment.NewLine + googlePlaceApiRespone.PlaceList.ElementAt(index).Vicinity
});
}
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(myMap);
var obj = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl;
obj.ItemsSource = placeToMapObjs;
myMap.SetView(new GeoCoordinate(Convert.ToDouble(currentLatitude), Convert.ToDouble(currentLongitude)), 16);
}
catch (Exception)
{
}
}
But can't no show in pushpin.
toolkit:Pushpin GeoCoordinate="{Binding Coordinate}" Content="{Binding Info}"

How to create nested JSON response with Entity Framework Query

I want to get a nested JSON reply with my EF query and not sure how to do this.
I have declared my Models as follows:
[Serializable]
public class StockReturnMethod
{
public int WarehouseID { get; set; }
public int ProductSKUID { get; set; }
public int LotID { get; set; }
public string LotName { get; set; }
public int AreaID { get; set; }
public string AreaName { get; set; }
public int BinID { get; set; }
public string BinName { get; set; }
public List<AvailibleStock> Stock { get; set; }
}
[Serializable]
public class AvailibleStock
{
public int WarehouseID { get; set; }
public int ProductSKUID { get; set; }
public string ProductSKUName { get; set; }
public string WarehouseName { get; set; }
public string Status { get; set; }
public int QtyUnassigned { get; set; }
}
Here is my EF query that I have so far.
{
return (from WH in SCMENT.Warehouses
join WL in SCMENT.WarehouseLots on WH.WarehouseID equals WL.WarehouseID
join WA in SCMENT.WarehouseAreas on WL.WarehouseLotID equals WA.WarehouseLotID
join WB in SCMENT.WarehouseBins on WA.WarehouseAreaID equals WB.WarehouseAreaID
join SLI in SCMENT.StockLineItems on WH.WarehouseID equals SLI.WarehouseID
join PSKU in SCMENT.ProductSKUs on SLI.ProductSKUID equals PSKU.ProductSKUID
where SLI.SystemAreaID == 1
select new StockReturnMethod()
{
WarehouseID = WH.WarehouseID,
LotID = WL.WarehouseLotID,
LotName = WL.WarehouseLotName,
AreaID = WA.WarehouseAreaID,
AreaName = WA.WarehouseAreaName,
BinID = WB.WarehouseBinID,
BinName = WB.WarehouseBinName,
ProductSKUID = PSKU.ProductSKUID,
Stock = (Will I create a sub query here?)
}
)
public List<AvailibleStock> Stock { get; set; }
Change this to:
public IList<AvailibleStock> Stock { get; set; }
Edit: Here's working sample from one of my projects that you can use as reference:
public class StatisticsModel
{
public int Id { get; set; }
public int ClientId { get; set; }
public int Opened { get; set; }
public IEnumerable<LocationsModel> Locations { get; set; }
}
public class LocationModel
{
public int Id { get; set; }
public string Name { get; set; }
public int OpenCount { get; set; }
}
return dbSet.Select(x => new StatisticsModel
{
Id = x.Id,
ClientId = x.ClientId,
Opened = x.OpenCount,
Locations = x.Locations.Select(z => new LocationsModel{
Id = z.Id,
Name = z.Store.Name,
OpenCount = z.OpenCount
})
})

Attempt to access the method failed: System.Collections.Generic.List`1..ctor()

I've this code through which I am retrieveing json data from my Localhost.But it is giving the error mentioned in my title.When I hover over the response while debugging.It shows me the correct response.I am using JSON.NET to parse json response.
var response = reader.ReadToEnd();
List<Company> cLst = JsonConvert.DeserializeObject<List<Company>>(response); //Error
this.Dispatcher.BeginInvoke(() =>
{
foreach (Company c in cLst)
{
ListBoxItemControl Li = new ListBoxItemControl();
Li.CompanyNameTextBlock.Text = c.CompanyName;
Li.PromotionTextBlock.Text = c.PromotionText;
listBox1.Items.Add(Li);
}
});
Here is the Company Class.
class Company
{
public string CompanyName {get; set;}
public string CompanySlogan { get; set; }
public string CompanyDescription { get; set; }
public string CompanyRating { get; set; }
public string CompanyDpPath { get; set; }
public string CompanyOtherInfo { get; set; }
public string CompanyFollowers { get; set; }
public int CompanyID { get; set; }
public int PromotionID { get; set; }
public string PromotionText { get; set; }
public string PromotionRating { get; set; }
public string PromotionPicPath { get; set; }
public string PromotionTitle { get; set; }
public int PromotionLikes { get; set; }
public int PromotionComments { get; set; }
}
Try making the Company class public
Take another class like,
public class RootObject
{
public List<Company> companies;
}
And then modify your code like this,
var jsonData = JsonConvert.DeserializeObject<RootObject>(response);
List<Company> cLst = jsonData.companies;
Try this and let me know.