问题
I am using a web JSON api to provide some values from a game market into c# objects. I am fairly new to c# and haven't worked with API's before.
Heres my code:
using System;
using System.Net;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace HttpsApiTest
{
class Program
{
public class ForQuery
{
public static bool bid { get; set; }
public static List<int> types { get; set; }
public static List<object> regions { get; set; }
public static List<object> systems { get; set; }
public static int hours { get; set; }
public static int minq { get; set; }
}
public class Buy
{
public static ForQuery forQuery { get; set; }
public static long volume { get; set; }
public static double wavg { get; set; }
public static double avg { get; set; }
public static double variance { get; set; }
public static double stdDev { get; set; }
public static double median { get; set; }
public static double fivePercent { get; set; }
public static double max { get; set; }
public static double min { get; set; }
public static bool highToLow { get; set; }
public static long generated { get; set; }
}
public class ForQuery2
{
public static bool bid { get; set; }
public static List<int> types { get; set; }
public static List<object> regions { get; set; }
public static List<object> systems { get; set; }
public static int hours { get; set; }
public static int minq { get; set; }
}
public class Sell
{
public ForQuery2 forQuery { get; set; }
public static int volume { get; set; }
public static double wavg { get; set; }
public static double avg { get; set; }
public static double variance { get; set; }
public static double stdDev { get; set; }
public static double median { get; set; }
public static double fivePercent { get; set; }
public static double max { get; set; }
public static double min { get; set; }
public static bool highToLow { get; set; }
public static long generated { get; set; }
}
public class RootObject
{
public Buy buy { get; set; }
public Sell sell { get; set; }
}
static void Main(string[] args)
{
string sURL = "https://api.evemarketer.com/ec/marketstat/json?typeid=1230®ionlimit=10000002";
StreamReader objReader = new StreamReader(WebRequest.Create(sURL).GetResponse().GetResponseStream());
string sLine = objReader.ReadLine();
JToken.Parse(sLine.Replace("[", "").Replace("]", "")).ToObject<RootObject>();
Console.WriteLine(Buy.max);
Console.WriteLine(Buy.highToLow);
Console.ReadLine();
}
}
}
and the web api JSON outputs this:
[
{
"buy": {
"forQuery": {
"bid": true,
"types": [
1230
],
"regions": [],
"systems": [],
"hours": 24,
"minq": 1
},
"volume": 5544790080,
"wavg": 11.43,
"avg": 10.86,
"variance": 4.38,
"stdDev": 2.09,
"median": 12,
"fivePercent": 13.75,
"max": 20,
"min": 5,
"highToLow": true,
"generated": 1551926105235
},
"sell": {
"forQuery": {
"bid": false,
"types": [
1230
],
"regions": [],
"systems": [],
"hours": 24,
"minq": 1
},
"volume": 258207299,
"wavg": 16.8,
"avg": 20.21,
"variance": 132.71,
"stdDev": 11.52,
"median": 15.99,
"fivePercent": 12.92,
"max": 60,
"min": 6,
"highToLow": false,
"generated": 1551926105235
}
}
]
I am not sure why Console.WriteLine(Buy.max); shows as 0 instead of 20 and Console.WriteLine(Buy.highToLow); shows as false instead of true. what am I doing wrong? I have looked for solutions to this issue for the past few hours to no avail. Any help would be greatly appreciated!
回答1:
What they said:
- Static members are usually for helpers or factory methods, or constants
- The API is returning an array (or List)
- That string-foo replacement is just sketchy at best. Any time you are working with a standard like JSON or XML, use the libraries to convert it to an object, then manipulate
Here's a working snippet:
using System;
using System.Net;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace HttpsApiTest
{
class Program
{
public class ForQuery
{
public bool bid { get; set; }
public List<int> types { get; set; }
public List<object> regions { get; set; }
public List<object> systems { get; set; }
public int hours { get; set; }
public int minq { get; set; }
}
public class Buy
{
public ForQuery forQuery { get; set; }
public long volume { get; set; }
public double wavg { get; set; }
public double avg { get; set; }
public double variance { get; set; }
public double stdDev { get; set; }
public double median { get; set; }
public double fivePercent { get; set; }
public double max { get; set; }
public double min { get; set; }
public bool highToLow { get; set; }
public long generated { get; set; }
}
public class ForQuery2
{
public bool bid { get; set; }
public List<int> types { get; set; }
public List<object> regions { get; set; }
public List<object> systems { get; set; }
public int hours { get; set; }
public int minq { get; set; }
}
public class Sell
{
public ForQuery2 forQuery { get; set; }
public int volume { get; set; }
public double wavg { get; set; }
public double avg { get; set; }
public double variance { get; set; }
public double stdDev { get; set; }
public double median { get; set; }
public double fivePercent { get; set; }
public double max { get; set; }
public double min { get; set; }
public bool highToLow { get; set; }
public long generated { get; set; }
}
public class RootObject
{
public Buy buy { get; set; }
public Sell sell { get; set; }
}
static void Main(string[] args)
{
string sURL = "https://api.evemarketer.com/ec/marketstat/json?typeid=1230®ionlimit=10000002";
StreamReader objReader = new StreamReader(WebRequest.Create(sURL).GetResponse().GetResponseStream());
string sLine = objReader.ReadLine();
var obj = JToken.Parse(sLine).ToObject<List<RootObject>>();
Console.WriteLine("Buy node:");
Console.WriteLine(" Max: " + obj[0].buy.max);
Console.WriteLine(" HighToLow: " + obj[0].buy.highToLow);
Console.WriteLine("Sell node:");
Console.WriteLine(" Max: " + obj[0].sell.max);
Console.WriteLine(" HighToLow: " + obj[0].sell.highToLow);
Console.ReadLine();
}
}
}
回答2:
The string replace is going to remove all instances of square brackets. You'd be better off deserializing the response as a list of RootObjects.
回答3:
class Data
{
public string DataPoint;
}
class CustomData
{
public Data Dp;
}
class Utility
{
public T JsonDeserialisation<T>(string jsonFile)
{
TextReader textReader = new StreamReader(jsonFile);
JsonTextReader jsonReader = new JsonTextReader(textReader);
return JsonSerializer.CreateDefault().Deserialize<T>(jsonReader);
}
}
Since you have all classes beforehand, you can the following code generic json deserializer. Here 'T' is CustomData class
来源:https://stackoverflow.com/questions/55036305/json-api-values-0-or-false