just trying to do a simple serialize(first time trying).
actually had this working up until I changed a few things and added a deserialize and added a class that made my other way no longer work.
basically I took what I had for deserialize json to object and tried to just reverse the order of things. but now I get an error at a foreach loop I'm not sure if I even need.
Once I get the serialize working I'm sure I will also be stuck on how to format the string as it enters the .json file so it appends properly but that is for another day.
here is error i received
System.NullReferenceException: 'Object reference not set to an instance of an object.'
i receive this exception on the line foreach(var translogs in Logs.transLogs)
here is my event.
Code
private void toolPull_Click(object sender, EventArgs e)
{
double cost = Convert.ToDouble(active_Cost.Text);
int serial = Convert.ToInt32(transactionSerial_Box.Text);
DateTime timeNow = DateTime.Now;
TransactionLogs Logs = new TransactionLogs();
foreach(var translogs in Logs.transLogs)
{
translogs.Employee = transactionEmployee_Box.Text;
translogs.Serial = serial;
translogs.Cost = cost;
translogs.Description = active_Description.Text;
translogs.CurrentDate = timeNow;
}
string stringJson = JsonConvert.SerializeObject(Logs);
StreamWriter sw = new StreamWriter(#"C:\transactionlog.json", append: true);
sw.WriteLine(stringJson);
sw.Close();
}
Here is the class to work with json
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class TransactionLogs
{
[JsonProperty("TransactionLog")]
public List<TransactionLog> transLogs { get; set; }
}
public partial class TransactionLog
{
[JsonProperty("employee")]
public string Employee { get; set; }
[JsonProperty("currentDate")]
public DateTime CurrentDate { get; set; }
[JsonProperty("serial")]
public int Serial { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("isPull")]
public bool IsPull { get; set; }
[JsonProperty("cost")]
public double Cost { get; set; }
}
}
and here is json file
{
"TransactionLog":[
{
"employee":"Joey",
"currentDate":"2021-11-03T11:49:13.5741628-04:00",
"serial":1111,
"description":"1/2-20 Threadmill",
"isPull":true,
"_ost":25.68
},
{
"employee":"joey",
"currentDate":"2021-11-03T11:50:34.6344474-04:00",
"serial":1000,
"description":"1/2-20 Threadmill",
"isPull":true,
"cost":25.68
},
{
"employee":"john",
"currentDate":"2021-11-03T11:50:40.9956616-04:00",
"serial":2000,
"description":"1/2-20 Threadmill",
"isPull":true,
"cost":25.68
},
{
"employee":"Jim",
"currentDate":"2021-11-03T11:51:24.5559292-04:00",
"serial":4565,
"description":"1/2-20 Threadmill",
"isPull":true,
"cost":25.68
}
]
}
Let me capture here the outcome of the comments.
There were two problems with these two lines:
TransactionLogs Logs = new TransactionLogs();
foreach(var translogs in Logs.transLogs)
The TransactionLogs's transLogs collection is not initialized, that's caused the NRE
After fixing that the foreach went through on an empty collection
The fix for the first problem:
Logs.transLogs = new List<TransactionLog>();
The fix for the second problem:
var transLogs = new TransactionLog()
{
Employee = transactionEmployee_Box.Text;
Serial = serial;
Cost = cost;
Description = active_Description.Text;
CurrentDate = timeNow;
};
Logs.transLogs.Add(transLogs);
So, rather than iterating through the empty collection, you had to populate it by adding a new member.
Related
I'm creating my first app in Xamarin.forms and want to add information about the characters. I followed the Microsoft docs but I keep getting the error that ".Add does not exist in the current context"
I've been the last hour or two searching online but nothing seems to have fixed it. Any help would be greatly appreciated, thanks!
using SQLite;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace CharCreator
{
public class Character
{
[PrimaryKey, AutoIncrement]
public int charIndex { get; set; }
public string charName { get; set; }
public string charClass { get; set; }
public string charRace { get; set; }
public int[] charStats { get; set; }
public int classId { get; set; }
public string className { get; set; }
}
}
public class CharClasses
{
List<CharClasses> classList = new List<CharClasses>();
classList.Add(new CharClasses() {classId = 1, className = "Barbarian"});
}
Your problem begins with the declaration
List<CharClasses> classList = new List<CharClasses>();
You are declaring a List of CharClasses instead of a List of Character. Then you try initialize this list with a first element. But you cannot add code outside a method.
So, if you really need to have CharClasses initialized with a List<Character> containig at least one element then you need to write this
public class CharClasses
{
public List<Character> classList = new List<Character>()
{
new Character {classId = 1, className = "Barbarian"}
};
--- other class method follows
}
This syntax is explained in documentation at Object and Collection Initializers
I have a class which basically contains a property like this:
public class Msg
{
[JsonProperty(PropertyName = "XD1703301059485299")]
public Shipping shipping { get; set; }
}
the problem is in this part:
[JsonProperty(PropertyName = "XD1703301059485299")]
And the dynamic property name that I get from server...
This property name can be any name that server returns. In this particular case it's able to map the JSON to my class since the property names are same... But when server returns something like this:
XS12394124912841
The object is the null....
How can I resolve property name to be dynamic ? Can someone help me out?
P.S. This is the JSON response itself:
{"status":1,"msg":{"dynamic_name":{"order_sn":"12312313123123123","order_status":"0","shipping_info":[{"shipping_name":"","shipping_no":"","shipping_img":"","shipping_code":"","shipping_time":"","track_goods":""}]}},"errcode":0}
So I don't think this problem is as dynamic as it sounds. You can probably just convert to a dyanmic object and explicitly handle conversions.
Sample solution below. I inserted a few values to show conversion works as expected.
Add nuget package Newtonsoft.Json
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
namespace Serialize
{
public class Shipping
{
[JsonProperty(PropertyName = "shipping_name")]
public String Name { get; set; }
[JsonProperty(PropertyName = "shipping_img")]
public String Img { get; set; }
[JsonProperty(PropertyName = "shipping_code")]
public String Code { get; set; }
}
public class Order
{
public Shipping shipping { get; set; }
[JsonProperty(PropertyName = "order_sn")]
public string SerialNumber { get; set; }
[JsonProperty(PropertyName = "order_status")]
public string Status { get; set; }
}
class Program
{
static void Main(string[] args)
{
/*
{
"status":1,
"msg": {
"dynamic_name": {
"order_sn": "12312313123123123",
"order_status":"0",
"shipping_info": [{
"shipping_name":"name",
"shipping_no":"",
"shipping_img":"img",
"shipping_code":"code",
"shipping_time":"",
"track_goods":""
}]
}
},
"errcode":0
}
* */
var raw = "{ \"status\":1, \"msg\":{\"dynamic_name\":{\"order_sn\":\"12312313123123123\",\"order_status\":\"0\",\"shipping_info\":[{\"shipping_name\":\"name\",\"shipping_no\":\"\",\"shipping_img\":\"img\",\"shipping_code\":\"code\",\"shipping_time\":\"\",\"track_goods\":\"\"}]}},\"errcode\":0}";
var incomingOrder = new Order();
// properties on dynamic objects are evaluated at runtime
dynamic msgJson = JObject.Parse(raw);
// you'll want exception handling around all of this
var order = msgJson.msg.dynamic_name;
// accessing properties is easy (if they exist, as these do)
incomingOrder.SerialNumber = order.order_sn;
incomingOrder.Status = order.order_status;
// JObject cast might not be necessary. need to check for array elements, etc.
// but it's simple to serialize into a known type
incomingOrder.shipping = ((JObject)(order.shipping_info[0])).ToObject<Shipping>();
}
}
}
Alternatively, if the property name is given at runtime, you can dereference properties with the indexer getter
dynamic msgJson = JObject.Parse(raw);
JObject order = msgJson.msg["XS12394124912841"];
incomingOrder.SerialNumber = order["order_sn"].ToObject<string>();
incomingOrder.Status = order["order_status"].ToObject<string>();
incomingOrder.shipping = order["shipping_info"][0].ToObject<Shipping>();
You can implement something like this with the help of System.Web.Helpers
using (StreamReader r = new StreamReader("sample.json"))
{
string json = r.ReadToEnd();
dynamic data = Json.Decode(json);
Console.WriteLine(data["your_property"]);
}
Here sample.json contains your sample JSON response.
I am not sure I am asking this question properly and have had trouble searching for what I need in this case. I have two classes. One consists of three items that I will assign.
namespace Common.PriceFeed
{
public class SurchargeSKUList
{
public string WebSKUID { get; set; }
public decimal AdditionalPrice { get; set; }
public string Currency { get; set; }
}
}
The other class is a list containing the items from the above class.
namespace Common.PriceFeed
{
public class BaseSurcharge
{
public List<SurchargeSKUList> SKUList { get; set; }
}
}
My problem is, then I try to use BaseSurcharge, I get errors like I am using as type as a variable or that I "cannot implicitly convert type..."
My .net code is below.
Thank you.
if (BaseSurcharges.Rows.Count > 0)
{
foreach (DataRow row in BaseSurcharges.Rows)
{
SurchargeSKUList newSKUList = new SurchargeSKUList();
newSKUList.WebSKUID = row["WebSKUID"].ToString();
newSKUList.AdditionalPrice = Convert.ToDecimal(row["AdditionalPrice"]);
newSKUList.Currency = row["Currency"].ToString();
BaseSurcharge newSurcharge = new BaseSurcharge();
newSurcharge.SKUList = List<SurchargeSKUList>newSKUList;
//BaseSurcharge List<SurchargeSKUList> newSurcharge = new BaseSurcharge
//BaseSurcharge newSurcharge = new BaseSurcharge();
//newSurcharge.SKUList = newSKUList;
}
}
newSurcharge.SKUList = List<SurchargeSKUList>newSKUList;
should be changed to:
newSurcharge.SKUList = new List<SurchargeSKUList>();
newSurcharge.SKUList.Add(newSKUList);
I didn't check this out on Visual Studio. So it might have some syntax errors.
But better yet - BaseSurcharge should have SKUList = new List<SurchargeSKUList>(); in its constructor.
I have a dictionary of strings and object that i obtained deserializing this json answer:
{"labels":[{"id":"1","descrizione":"Etichetta interna","tipo":"0","template_file":"et_int.txt"},{"id":"2","descrizione":"Etichetta esterna","tipo":"1","template_file":"et_ext.txt"}],"0":200,"error":false,"status":200}
using the code:
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Now i want to loop only trought the objects inside the "labels" key.
I tried
foreach (var outer in labels["labels"]){/* code */}
but i got error:
CS1579: foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'.
Solved replacing the dictionary with a class, thank you
Create a class to deserialize your json:
To create classes, you can copy the json in clipboard and use the
Edit / Paste special / Paste JSON as class
in visual studio (I use vs2013).
[TestMethod]
public void test()
{
string json = "{\"labels\" : [{\"id\" : \"1\",\"descrizione\" : \"Etichetta interna\",\"tipo\" : \"0\",\"template_file\" : \"et_int.txt\"}, {\"id\" : \"2\",\"descrizione\" : \"Etichetta esterna\",\"tipo\" : \"1\",\"template_file\" : \"et_ext.txt\"}],\"0\" : 200,\"error\" : false,\"status\" : 200}";
var root = JsonConvert.DeserializeObject<Rootobject>(json);
foreach (var label in root.Labels)
{
//Use label.Id, label.Descrizione, label.Tipo, label.TemplateFile
}
}
public class Rootobject
{
public Label[] Labels { get; set; }
public int _0 { get; set; }
public bool Error { get; set; }
public int Status { get; set; }
}
public class Label
{
public string Id { get; set; }
public string Descrizione { get; set; }
public string Tipo { get; set; }
public string TemplateFile { get; set; }
}
You need to loop through your dictionary.
foreach(KeyValuePair<string, Object> entry in labels)
{
// do something with entry.Value or entry.Key
}
Once you start looping through it you will get access to key and value. Since you are interested to look at entry.value you can do operation on that easily. Currently your dictionary value is type of object which does not have an enumerator
Your problem is that you've defined the Type of Value for each dictionary entry as object. C# can't know how to loop over on object. So you need to work out what type is actually inside the object once the JavaScriptSerializer have parsed the JSON. One way is
var t = typeof(labels["labels"]);
Once you know what type the serializer is creating, all you need to do is cast the object back to that type. For example, assuming it's a list of objects
var labels = (List<object>)labels["labels"];
foreach (var label in labels)
{
}
Alternatively, if each object in the JSON is the same, you could try create the dictionary as the type you need. So you serializing becomes
var labels = new JavaScriptSerializer()
.Deserialize<Dictionary<string, List<object>>>(json);
A possible solution:
static void Main(string[] args) {
string json = #"{'labels':[{'id':'1','descrizione':'Etichetta interna','tipo':'0','template_file':'et_int.txt'},{'id':'2','descrizione':'Etichetta esterna','tipo':'1','template_file':'et_ext.txt'}],'0':200,'error':false,'status':200}";
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
IEnumerable inner_labels = labels["labels"] as IEnumerable;
if (inner_labels != null) {
foreach (var outer in inner_labels) {
Console.WriteLine(outer);
}
}
}
Otherwise, you can create a class with deserialization information and instruct the deserializer to deserialize your json string to that type:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
[Serializable]
public class JsonData {
[XmlElement("labels")]
public List<JsonLabel> labels { get; set; }
[XmlElement("0")]
public int zero { get; set; }
[XmlElement("error")]
public bool error { get; set; }
[XmlElement("status")]
public int status { get; set; }
}
[Serializable]
public class JsonLabel {
[XmlElement("id")]
public int id { get; set; }
[XmlElement("descrizione")]
public string descrizione { get; set; }
[XmlElement("tipo")]
public int tipo { get; set; }
[XmlElement("template_file")]
public string template_file { get; set; }
}
class Program {
static void Main(string[] args) {
string json = #"your json string here...";
var jsonData = new JavaScriptSerializer().Deserialize<JsonData>(json);
foreach (var label in jsonData.labels) {
Console.WriteLine(label.id);
}
}
}
Could you please try below snippet?
It might be help you.
foreach (var item in labels["labels"] as ArrayList)
{
Console.Write(item);
}
For Windows 8 application development environment.
Code:
var deserialized = JsonConvert.DeserializeObject<RootObject>(json);
listView.ItemsSource = deserialized; // error
Data model:
public class C
{
public List<Y> programs { get; set; }
public string name { get; set; }
public int code { get; set; }
}
public class RootObject
{
public List<C> cs { get; set; }
public string date { get; set; }
}
public class Y
{
public string category { get; set; }
public string time { get; set; }
public string name { get; set; }
}
What can I do ? I don't find solution.
ItemsSource is looking for an IEnumerable, but you're providing a single object in RootObject. You'd get the same error if you create one of your RootObject instances in code and try the same assignment.
What specifically should be displaying in the list? If you simply change your code to:
listView.ItemsSource = deserialized.cs;
the listView should display your C objects.
I always have trouble figuring out how to go from the serializer output. I do have working code (windows 8 store) that I'm pasting below. It is pretty obvious what it does.
HttpResponseMessage responseGetEmailByPersonsBare =
await clientGetEmailByPersonsBare.PostAsync(UrlBase + EmailDetailGetEmailByPersonsBare, contentGetEmailByPersonsBare);
Stream myStream = await responseGetEmailByPersonsBare.Content.ReadAsStreamAsync();
var djsGetEmailByPersonsBare = new DataContractJsonSerializer(typeof(AEWebDataStructures.RootObjectEmailDetail));
var rootObjectEmailDetail = (AEWebDataStructures.RootObjectEmailDetail)djsGetEmailByPersonsBare.ReadObject(myStream);
responseGetEmailByPersonsBare.EnsureSuccessStatusCode();
returnTaskInfo.EmailDetails = rootObjectEmailDetail.Data;
returnTaskInfo.StatusReturn = AEWebDataStructures.StatusReturn.Success;