Newtonsoft Json is not serializing class - json

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; }

Related

Deserialize multi-part JSON with DataContractJsonSerializer

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.

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; }
}

I can't load data from json to tableview on xamarin

I need your help.
UIViewControl....
var data= await track.QueryCategory(link);
if(data!=null)
{
var get_data=JsonConvert.DeserializeObject<Categorycs.RootObject>(data);
_table = new UITableView {
Frame = new CoreGraphics.CGRect (0, 0, View.Bounds.Width, View.Bounds.Height),
Source= new TableSoundCloudSource(get_data.tracks)
};
View.AddSubview (_table);
}
TableSource.cs
public class TableSource: UITableViewSource
{
List<string> tableItems;
string cellIdentifier="TableCell";
public TableSource (List<string> items)
{
tableItems = items;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return tableItems;
}
public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
if (cell == null) {
cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
} else
cell.TextLabel.Text = tableItems [indexPath.Row];
return cell;
}
}
}
Public class Categorycs
{
public class RootObject
{
public List<Track> tracks { get; set; }
public string tag { get; set; }
public string next_href { get; set; }
}
}
public class Track
{
public string urn { get; set; }
public string uri { get; set; }
public string permalink { get; set; }
public string permalink_url { get; set; }
public string title { get; set; }
public string description { get; set; }
public string track_type { get; set; }
public string genre { get; set; }
public string tag_list { get; set; }
public int duration { get; set; }
public bool? downloadable { get; set; }
public string download_url { get; set; }
public int original_content_size { get; set; }
public bool streamable { get; set; }
public bool commentable { get; set; }
public string sharing { get; set; }
public string created_at { get; set; }
public string updated_at { get; set; }
public string isrc { get; set; }
public string state { get; set; }
public int? likes_count { get; set; }
public int? playback_count { get; set; }
public int? reposts_count { get; set; }
public int? download_count { get; set; }
public int? comment_count { get; set; }
public string embeddable_by { get; set; }
public string license { get; set; }
public string artwork_url { get; set; }
public string stream_url { get; set; }
public string waveform_url { get; set; }
public string purchase_url { get; set; }
public string purchase_title { get; set; }
public bool reveal_comments { get; set; }
public bool reveal_stats { get; set; }
public bool feedable { get; set; }
public bool geo_blocking { get; set; }
public object geo_blockings { get; set; }
public bool embeddable { get; set; }
public string label_name { get; set; }
public string release_date { get; set; }
public object schedule { get; set; }
public Visuals visuals { get; set; }
public object publisher_metadata { get; set; }
public object monetization { get; set; }
public int user_id { get; set; }
public User user { get; set; }
public string policy { get; set; }
public string monetization_model { get; set; }
public object secret_token { get; set; }
public object secret_uri { get; set; }
public object publisher_state { get; set; }
public string last_modified { get; set; }
public object disabled_at { get; set; }
public object disabled_reason { get; set; }
public bool has_downloads_left { get; set; }
public string kind { get; set; }
public int id { get; set; }
}
Errors:Error CS1503: Argument #1' cannot
convertSystem.Collections.Generic.List<'Categorycs.Track'>' expression
to type `string[]'.
I have try to replaced 'List<'string'>'to List<'Categorycs.Track'> but app don't run.
here, you are passing TableSource get_data.tracks, which is a List<Track>:
Source= new TableSoundCloudSource(get_data.tracks)
but here, you are telling TableSource to accept a List<string>
public TableSource (List<string> items)
this is a "type mismatch" - it is expecting an object of Type A, but you are passing it an object of Type B. In some cases it can automatically convert A to B, but not in this case.
(I'm assuming that the fact that it is named "TableSoundCloudSource" in one place and "TableSource" in another is a cut-and-paste error. If not, then that is another problem with your code.)
You either need to modify your TableSource to accept a List<Track> (which will require several changes) or you need to pass it a List<string>, which is what it currently expects.
The 2nd error you're reporting is because of this:
public override nint RowsInSection(UITableView tableview, nint section)
{
return tableItems;
}
that function should return an nint, but you are returning tableItems, which is a List (it doesn't really matter what kind of list). What you really want to return is tableItems.Count, which is the number of elements in your list.
This code was always wrong, but because of the earlier problem the compiler probably never got to it to tell you it was bad. Debugging is like this - fixing one bug can uncover (or create) several more. You just have to slog through them until it works.
Finally,
cell.TextLabel.Text = tableItems [indexPath.Row];
Text is a string, tableItems[indexPath.Row] is a Track. You can't assign a Track to a string - that's another type mismatch. Instead, do this
cell.TextLabel.Text = tableItems [indexPath.Row].title;
Since the title property of Track is a string, that works (I'm assuming you want to use title - you can use any property that is a string, or can be automatically converted to a string)
Note that this really has nothing to do with Xamarin - it's basic C#, and conceptually basic programming.

ASP.NET MVC4: How to convert an IEnumerable to a string for ViewBag

This is what I'm trying to do, but it doesn't work:
HardwareType hwt = new HardwareType { HType = "PC" };
IEnumerable<Hardware> Pcs = db.Hardware.Where(h => h.HardwareType.Contains(hwt));
ViewBag.Pcs = Pcs.ToString();
So how do I convert my IEnumerable to a string (or other primitive data type) so the compiler won't give me an error when I try to use it in my Razor?
#foreach (var item in ViewBag.Pcs) {
<li><i class="icon-hdd"></i> #item.HType</li>
}
Hardware class:
public class Hardware
{
public int Id { get; set; }
public virtual ICollection<DeviceType> Type { get; set; }
public string AssetTagId { get; set; }
public virtual ICollection<Manufacturer> Manufacturer { get; set; }
[Required]
[StringLength(50)]
public string ServiceTagId { get; set; }
[Required]
[StringLength(50)]
public string SerialNumber { get; set; }
[Required]
[StringLength(75)]
public string ProductNumber { get; set; }
// [Required]
[StringLength(20)]
public string PurchaseDate { get; set; }
[StringLength(20)]
public string WarrantyExpiration { get; set; }
[Required]
[StringLength(20)]
public string WarrantyType { get; set; }
public virtual ICollection<Location> Location { get; set; }
public virtual ICollection<HardwareType> HardwareType { get; set; }
[Required]
[StringLength(2000)]
public string Notes { get; set; }
public string POATag { get; set; }
}
HardwareType class:
public class HardwareType
{
public int Id { get; set; }
[Required]
[StringLength(128)]
public string HType { get; set; }
public virtual ICollection<Hardware> Hardware { get; set; }
}
It looks to me as if the problem is that you are converting it to a string, here:
ViewBag.Pcs = Pcs.ToString();
Why are you doing that? It looks like you want to iterate over the individual items within the sequence within your view. Either use:
ViewBag.Pcs = Pcs;
or
ViewBag.Pcs = Pcs.ToList();
if you want to force the query to be materialized.
EDIT: Looking at the error again, I suspect it's actually the Where clause that's the problem. I suspect you really want:
var pcs = db.Hardware.Where(h => h.HardwareType.Any(hwt => hwt.HType == "PC"));
ViewBag.Pcs = pcs.ToList(); // Materialize the query
The problem is trying to use your hwt value as input to the query...

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.