I have the following JSON input from a webserver:
{
"success":1,
"return":{
"45677":{
"pair":"aaaa",
"type":"bbbbbbbb",
"amount":1.00000000,
"rate":3.00000000,
"timestamp_created":1342448420,
"status":0
}
}
}
I'm using Newtonsoft JSON.net.
I have the following class:
public class ActiveOrders
{
public Dictionary<int, Order> Dictionary { get; private set; }
public static ActiveOrders ReadFromJObject(JObject o)
{
if (o == null) return null;
return new ActiveOrders
{
Dictionary =
o.OfType<KeyValuePair<string, JToken>>()
.ToDictionary(item => int.Parse(item.Key), item => Order.ReadFromJObject(item.Value as JObject))
};
}
}
It doesn't return null, which means the answers ok, as it is in my other methods. But the
result of ActiveOrders.Dictionary is empty.
Here is the class Order:
public class Order
{
public BtcePair Pair { get; private set; }
public TradeType Type { get; private set; }
public decimal Amount { get; private set; }
public decimal Rate { get; private set; }
public UInt32 TimestampCreated { get; private set; }
public int Status { get; private set; }
public static Order ReadFromJObject(JObject o)
{
if (o == null) return null;
return new Order
{
Pair = BtcePairHelper.FromString(o.Value<string>("pair")),
Type = TradeTypeHelper.FromString(o.Value<string>("type")),
Amount = o.Value<decimal>("amount"),
Rate = o.Value<decimal>("rate"),
TimestampCreated = o.Value<UInt32>("timestamp_created"),
Status = o.Value<int>("status")
};
}
}
The types are correct, as are my other classes, they all look the same.
I would like some ideas to make it work. Any advice?
Below code works.....
var obj = JsonConvert.DeserializeObject<ActiveOrders>(json);
public class ActiveOrders
{
public int success { get; set; }
public Dictionary<string,Order> #return { get; set; }
}
public class Order
{
public string pair { get; set; }
public string type { get; set; }
public double amount { get; set; }
public double rate { get; set; }
public int timestamp_created { get; set; }
public int status { get; set; }
}
Related
can someone tell me how to deserialize a json object using either a path to another json file or a json object?
I am trying to make a game where its entirely constructed of config files.
basically I would take either these two...
{
"LevelConfig" : {
"SkillGain" : 0.01,
"MagicGain" : 0.01,
"XpScale" : 50.0,
"HpScale" : 0.01,
"MpScale" : 0.01
}
}
or
{
"LevelConfig" : "../Level.level" (only returns json object if file exists else it tries to return string)
}
and convert them into these
public class JLevel
{
public float SkillGain { get; set; }
public float MagicGain { get; set; }
public float XpScale { get; set; }
public float HpScale { get; set; }
public float MpScale { get; set; }
}
public class JEntity
{
public string Name { get; set; }
public int Hp { get; set; }
public int Mp { get; set; }
public int Xp { get; set; }
public JLevel LevelConfig { get; set; }
public JColor ColorConfig { get; set; }
public JPhysics PhysicsConfig { get; set; }
}
class Entity
{
public Entity Load(string filename)
{
return ???;
}
public void Save(string filename)
{
???;
}
}
now I know I can just use JsonConvert.DeserializeObject() but that doesn't check for json paths.
First you need to create a class for this Json Object
The name of class should be the same as Object name in JSON
{
"LevelConfig" : {
"SkillGain" : 0.01,
"MagicGain" : 0.01,
"XpScale" : 50.0,
"HpScale" : 0.01,
"MpScale" : 0.01
}
}
public class LevelConfig
{
public double SkillGain { get; set; }
public double MagicGain { get; set; }
public double XpScale { get; set; }
public double HpScale { get; set; }
public double MpScale { get; set; }
}
public class Example
{
public LevelConfig LevelConfig { get; set; }
}
then you need to desalinize it using Newtonsoft
JsonConvert.DeserializeObject<Example>(Json);
Json should be a string. If its an Object the you need to use this on
JsonConvert.DeserializeObject<Example>(JsonConvert.SerializeObject(Json));
class Program
{
public static void Main()
{
var str = "{ LevelConfig : \"level.json\"}";
var levelConfigs = JsonConvert.DeserializeObject<LevelConfigs>(str);
var fileTxt = GetFileText(levelConfigs.LevelConfig);
JLevel level = JsonConvert.DeserializeObject<JLevel>(fileTxt);
Console.WriteLine(level.HpScale);
Console.ReadLine();
}
private static string GetFileText(string jsonFile)
{
return File.ReadAllText(jsonFile);
}
}
public class LevelConfigs
{
public string LevelConfig { get; set; }
}
public class JLevel
{
public float SkillGain { get; set; }
public float MagicGain { get; set; }
public float XpScale { get; set; }
public float HpScale { get; set; }
public float MpScale { get; set; }
}
public class JEntity
{
public string Name { get; set; }
public int Hp { get; set; }
public int Mp { get; set; }
public int Xp { get; set; }
public JLevel LevelConfig { get; set; }
}
you can change your implementation of GetFileText for your needs
hi i've a complex class with generic list and i need to check difference from two classes
this is is my class
public partial class Contatto
{
[DataMember]
public int? Id { get; set; }
private int? tyContatto { get; set; }
[DataMember]
public DContatto DContatto { get; set; }
[DataMember]
public string Cognome { get; set; }
[DataMember]
public string Nome { get; set; }
[DataMember]
public string RagioneSociale { get; set; }
private int? tySesso{get; set;}
[DataMember]
public DSesso DSesso { get; set; }
[DataMember]
public DateTime TsValidita { get; set; }
[DataMember]
public DateTime DtNascita { get; set; }
private int? idComune { get; set; }
[DataMember]
public Comune Comune { get; set; }
[DataMember]
public string CdFiscale { get; set; }
[DataMember]
public string PartitaIva { get; set; }
private int? tyIso { get; set; }
[DataMember]
public DIso DIso { get; set; }
[DataMember]
public int? IdUser { get; set; }
[DataMember]
public string UserId { get; set; }
[DataMember]
public List<Telefono> LsTelefono { get; set; }
[DataMember]
public List<Mail> LsMail { get; set; }
[DataMember]
public List<Indirizzo> LsIndirizzo { get; set; }
}
and this is my recursively method
private static object CheckRecursivelyDifference(object old, object nuevo)
{
var oType = old.GetType();
foreach (var oProperty in oType.GetProperties())
{
var oOldValue = oProperty.GetValue(old, null); //letto dal SqlServer
var oNewValue = oProperty.GetValue(nuevo, null); //letto dal gestionale
if (oProperty.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary")
CheckRecursivelyDifference(oOldValue, oNewValue);
else
{
// this will handle the scenario where either value is null
if (!object.Equals(oOldValue, oNewValue))
{
if (oNewValue == null && oOldValue != null) //vince sempre il vecchio gestionale
oProperty.SetValue(nuevo, oOldValue);
}
}
}
return nuevo;
}
the method work for a normal class but when read a property as System.Collection.Generic.List<> not work
my question is how i can check System.Collection.Generic.List<> and inheritance property.
thank you in advance for your help
What you can do when it comes to objects that are lists is to check if they are indeed lists,
public static bool IsGenericList(object value)
{
if (value == null)
return false;
try
{
var val = value as IList;
if (val == null)
return false;
if ((typeof(BaseConversion)).IsAssignableFrom(val.GetType().GetGenericArguments()[0]))
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
also exclude indexed parameters like this["test"],etc
objType.GetProperties().Where(x => x.GetIndexParameters().Length == 0
on your
var oProperty in oType.GetProperties()
line.
I have the following method which is used to retrieve all values as strings from an object using reflection. The object can have IEnumerables within them and I also want to retrieve these values. A list of ignore fields also needs to be taken into account so that those field's values are not returned.
public static IEnumerable<string> StringContent(this object obj, IEnumerable<string> ignoreProperties = null)
{
Type t = obj.GetType();
foreach (var prop in t.GetProperties())
{
if (ignoreProperties != null && ignoreProperties.Contains(field.Name))
{
continue;
}
var value = prop.GetValue(obj);
if (value != null)
{
if (value is IEnumerable<object>)
{
foreach (var item in (IEnumerable<object>)value)
{
foreach (var subValue in item.StringContent())
{
yield return subValue.ToString();
}
}
}
else
{
yield return value.ToString();
}
}
}
}
This method does work perfectly and gives me the correct result. However, I need to speed it up as much as possible because this is performed a lot of times.
Does anybody have any suggestions?
Thanks in advance!
** EDIT **
Example Test Case:
[TestMethod]
public void StringContent()
{
Project project = projectA;
List<string> ignoreFields = new List<string>() { "SalesEngineer", "CreationDate" };
var result = project.StringContent(ignoreFields);
Assert.IsTrue(result.Count() == 26);
}
Project Object:
public class Project : IEntity
{
public Project()
{
Products = new List<ProjectProducts>();
}
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public string SalesEngineer { get; set; }
public string SalesEngineerEmail { get; set; }
public int? TeamId { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Originator { get; set; }
public string ContactName { get; set; }
public string MainClient { get; set; }
public string Contractor { get; set; }
public string ContractorContactName { get; set; }
public string ContractorLocation { get; set; }
public string Wholesaler { get; set; }
public string WholesalerContactName { get; set; }
public string WholesalerLocation { get; set; }
public float EstimatedValue { get; set; }
public float CalculatedValue {
get { return EstimatedValue/Convert.ToSingle(Currency != null ? Currency.Rate : (decimal)1.0); }
}
public int Probability { get; set; }
public int SectorId { get; set; }
public int TypeId { get; set; }
public string StatusCode { get; set; }
public string LostTo { get; set; }
public int ReasonId { get; set; }
public string SecondaryEngineer { get; set; }
public float SplitPercentage { get; set; }
public DateTime ExpectedOrder { get; set; }
public DateTime? RequiredOnSiteBy { get; set; }
public bool LightingDesignRequired { get; set; }
public string ReasonForLightingDesign { get; set; }
public DateTime? DesignRequiredBy { get; set; }
public DateTime? FollowUp { get; set; }
public string Comments { get; set; }
public int CurrencyId { get; set; }
public bool Void { get; set; }
public string AttachmentFolder { get; set; }
public virtual Currency Currency { get; set; }
public virtual Reason Reason { get; set; }
public virtual ProjectStatus Status { get; set; }
public virtual ProjectType Type { get; set; }
public virtual Sector Sector { get; set; }
public virtual ICollection<ProjectProducts> Products { get; set; }
public virtual Team Team { get; set; }
public object Key
{
get { return Id; }
}
}
You can use stringify package.
It exists in Nuget.
You can Hide parameters with Hidden attribute.
You can print every object with a.stringify();
I am trying to make retrieve a certain string from a list of object in c#( let's call that list userlist)(the list has about 1600 elements in it and each object has about 15 different parameters).
So this is the code that I have:
private List<String> getGameList(CommandEventArgs e) {
List<String> allgames = new List<string>();
List<User> userlist = e.Server.Users.ToList();
foreach (User u in userlist)
{
if (u.CurrentGame.ToString() != "")
{
if (u.CurrentGame.Value.Name != null)
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
But it everytime that this bit of code runs the list that gets returned has only one or two results in it while it should retrieve a lot more.
To give more information about the code:
User is the object with about 15 parameters/objects under it
u.CurrentGame retrieves an object called "Game" that is under a "User"
u.CurrentGame.Value.Name is the string that I want to retrieve and add in the new "allgames" list
I know the Insert(0,String) is strange but for some reason a simple .Add didn't seem to work properly either
Any idea why I only have 1 or 2 results and not more while it should?
I can definitly provide more information if needed.
Thank you
Without seeing the complete code my guess is that you either have an early return or a break somewhere in your loop where you probably should have been using a continue instead to continue iterating through the list.
You should also probably be using string.IsNullOrEmpty(s) instead of the comparison with "".
That's all the help I can give with the information you've provided.
I did small experiment 3 cases, and all 3 cases works somehow:
using System;
using System.Collections.Generic;
using System.Linq;
namespace p44785433
{
class Program
{
static List<User> userList = UserFactory.GenerateUsers();
static void Main(string[] args)
{
Console.WriteLine("Number Of Users: {0}", userList.Count);
var x = getGameList(userList); // 1600 on output
var y = getGameListUpdated(userList); // 1600< on output depend of randomized empty name
var z = getGameListLinq(userList); // 1600< on output depend of randomized empty name
}
private static List<String> getGameList(List<User> parUserList)
{
List<string> allgames = new List<string>();
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
foreach (User u in userlist)
{
if (u.CurrentGame.ToString() != "")
{
if (u.CurrentGame.Value.Name != null)
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
private static List<String> getGameListUpdated(List<User> parUserList)
{
List<string> allgames = new List<string>();
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
foreach (User u in userlist)
{
if (!string.IsNullOrEmpty(u.CurrentGame.ToString()))
{
if (!string.IsNullOrEmpty(u.CurrentGame.Value.Name))
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
private static List<String> getGameListLinq(List<User> parUserList)
{
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
var x = userList.Where(r => !string.IsNullOrEmpty(r.CurrentGame.ToString()) && !string.IsNullOrEmpty(r.CurrentGame.Value.Name)); // remove empty
var y = x.Select(r => r.CurrentGame.Value.Name); // select strings
var z = y.Reverse(); // reverse order instead of insert
return z.ToList();
}
}
internal class User
{
public Game CurrentGame { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
internal static User CreateDummy()
{
return new User()
{
CurrentGame = Game.CreateDummy(),
Par6 = UserFactory.Rnd.NextDouble().ToString(),
Par12 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
internal static class UserFactory
{
static Random _rnd;
internal static Random Rnd
{
get
{
if (_rnd == null) _rnd = new Random();
return _rnd;
}
}
internal static List<User> GenerateUsers()
{
List<User> list = new List<User>();
for (int i = 0; i < (int)1600; i++)
{
list.Add(User.CreateDummy());
}
return list;
}
}
internal class Game
{
public Value Value { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
public override string ToString()
{
return Par6;
}
internal static Game CreateDummy()
{
return new Game()
{
Value = Value.CreateDummy(),
Par6 = UserFactory.Rnd.NextDouble().ToString(),
Par12 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
internal class Value
{
public string Name { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
internal static Value CreateDummy()
{
return new Value()
{
Name = (UserFactory.Rnd.Next(10)!=0 ? string.Format("XXA{0}XAA", UserFactory.Rnd.NextDouble()): string.Empty),
Par5 = UserFactory.Rnd.NextDouble().ToString(),
Par11 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
}
My classes are defined below
public class HotelRoomResponse
{
public string rateCode { get; set; }
public string rateDescription { get; set; }
public RoomType RoomType { get; set; }
public string supplierType { get; set; }
public int propertyId { get; set; }
public BedTypes BedTypes { get; set; }
public string smokingPreferences { get; set; }
public int rateOccupancyPerRoom { get; set; }
public int quotedOccupancy { get; set; }
public int minGuestAge { get; set; }
public RateInfos RateInfos { get; set; }
public ValueAdds ValueAdds { get; set; }
public string deepLink { get; set; }
public RoomImages RoomImages { get; set; }
}
public class ValueAdd
{
[JsonProperty(PropertyName = "#id")]
public string id { get; set; }
public string description { get; set; }
}
public class ValueAdds
{
private string valueaddsize="0";
[JsonProperty(PropertyName = "size")]
[DefaultValue("0")]
public string size
{
get
{
return !string.IsNullOrEmpty(valueaddsize)
? valueaddsize
: ((DefaultValueAttribute)
(TypeDescriptor.GetProperties(this)["size"].Attributes[
typeof(DefaultValueAttribute)])).Value.ToString();
}
set { valueaddsize = value; }
}
[JsonConverter(typeof(ObjectToArrayConverter<ValueAdd>))]
public List<ValueAdd> ValueAdd { get; set; }
}
public class RoomImage
{
//// private string useurl = "~/no-picture-available.jpg";
// [DefaultValue("~/no-picture-available.jpg")]
// public string url { get; set; }
private string useurl="~/no-picture-available.jpg";
[DefaultValue("~/no-picture-available.jpg")]
public string url
{
get
{
return !string.IsNullOrWhiteSpace(useurl)
? useurl
: ((DefaultValueAttribute)
(TypeDescriptor.GetProperties(this)["url"].Attributes[
typeof(DefaultValueAttribute)])).Value.ToString();
}
set { useurl = value; }
}
}
public class RoomImages
{
public string size { get; set; }
public RoomImage RoomImage { get; set; }
}
While in deserialization process a few parameters are missing i.e each time a few hotels will produce RoomImages and ValueAdds and a few hotel will not .
My Question is instead of sending Nulls after deserialization process, I am try to set default values but those values are not reflected after deserialization. How can I set default values to RoomImages values as "No images url" and ValueAdds as "No value adds "?
Json.Net will ignore the properties which do not exist in the json, but I think you talk about the case-2 (below). Then using NullValueHandling enum would be enough.
//Case 1 (Json doesn't contain the property)
var image = JsonConvert.DeserializeObject<RoomImage>("{}");
Console.WriteLine(image.Url); //<-- ~/no-picture-available.jpg
//Case 2 (Property is explicitly set to null)
var settings = new JsonSerializerSettings() {NullValueHandling = NullValueHandling.Ignore };
image = JsonConvert.DeserializeObject<RoomImage>("{\"Url\":null}", settings);
Console.WriteLine(image.Url); //<-- ~/no-picture-available.jpg
public class RoomImage
{
string _url = "~/no-picture-available.jpg";
public string Url { get { return _url; } set { _url = value; } }
}