Я имею дело с JSON в первый раз и получаю данные от OpenTSDB. Я создал класс C# для десериализации JSON, но получаю ошибку «Невозможно десериализовать текущий массив JSON», как описано ниже.JSON object deserialize to C# object - OpenTSDB
Мой C# код, чтобы получить JSON:
var request = WebRequest.Create("http://localhost:4242/api/query?start=2013/08/21-12:00:00&end=2013/08/22-12:00:00&m=sum:tcollector.collector.lines_sent&o=&yrange=%5B0:%5D&wxh=924x773");
request.ContentType = "application/json; charset=utf-8";
string text;
try
{
var response = (HttpWebResponse) request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
uxResponse.Text = text;
OpenTSDBResponse myObject = (OpenTSDBResponse)Newtonsoft.Json.JsonConvert.DeserializeObject(text, typeof(OpenTSDBResponse));
var variable = Newtonsoft.Json.JsonConvert.DeserializeObject(text);
//var tester = myObject;
}
catch (Exception ex)
{
uxResponse.Text = GetFullExceptionMessage(ex);
}
JSON я получаю из кода выше (то есть 'текст' переменной):
[{
"metric":"tcollector.collector.lines_sent",
"tags":
{
"host":"ubuntu1"
},
"aggregateTags":["collector"],
"dps":
{
"1377050434":1271779.0,
"1377050494":1272073.0,
"1377050554":1272502.0,
"1377050614":1273632.0,
"1377050674":1273867.0
}
}]
Моя C# классы
internal class OpenTSDBResponse
{
[JsonProperty("metric")]
public string Metric { get; set; }
[JsonProperty("tags")]
public Tags Tags { get; set; }
[JsonProperty("aggregateTags")]
public string[] AggregateTags { get; set; }
[JsonProperty("dps")]
public List<TimeValue> TimeValues { get; set; }
}
internal class Tags
{
[JsonProperty("host")]
public string Host { get; set; }
}
internal class TimeValue
{
[JsonProperty("Time")]
public double Time { get; set; }
[JsonProperty("Value")]
public double Value { get; set; }
}
Ошибка при десериализации объекта:
Не может десериализации текущий массив JSON (например, [1,2,3]) в тип 'MyNamespace.OpenTSDBResponse', потому что для этого требуется объект JSON (например, {"name": "value"}) для десериализации. Чтобы исправить эту ошибку , либо измените JSON на объект JSON (например, {"name": "value"}) или изменить десериализованный тип на массив или тип, который реализует интерфейс коллекции (например, ICollection, IList), например List, который может десериализоваться из массива JSON , JsonArrayAttribute может также быть добавлены к типу, чтобы заставить его десериализации из JSON array.Path «», строка 1, позиция 1.
Дополнительная информация
Я использовал Codeproject десериализации JSON проект для создания моих базовых классов, но он создал новое свойство C# для каждого «1377050434»: 1271779.0, поэтому я обновил свой класс TimeValue. http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-C
Вопрос:
Как я могу получить это в соответствующий C# класса структуры?
Дополнительная информация в ответ на комментарии пользователей ниже:
bjaminn Комментарий: Я считаю, что JSON вы получаете массив. Исключение пытается сказать, что вы конвертируете объект [] в OpenTSDBResponse, когда действительно хотите OpenTSDBResponse []. Другим способом отладки этого было бы посмотреть переменную переменной и посмотреть, какой тип она находится в отладчике. Конечно, строка, которая выдает исключение, должна быть прокомментирована.
Результат: Я изменил десериализации как этот
OpenTSDBResponse [] MyObject = (OpenTSDBResponse []) Newtonsoft.Json.JsonConvert.DeserializeObject (текст, typeof (OpenTSDBResponse []));
но получил следующее сообщение об ошибке, когда я побежал:
Не может десериализации текущего объекта JSON (например, { «имя»: «значение»}) в тип «System.Collections.Generic.List`1 [MyNamespace.OpenTSDBResponseJsonTypes.TimeValue] ', потому что для этого требуется, чтобы десериализован массив JSON (например, [1,2,3]). Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3]) или изменить десериализованный тип, чтобы он был обычным типом .NET (например, не примитивным типом типа integer, а не типом коллекции, подобным массиву или списку), который можно десериализовать из объекта JSON. JsonObjectAttribute также может быть добавлен к типу, чтобы заставить его десериализацию JSON из object.Path «[0] .dps.1377050434», строки 1, позиция 121.
Дополнительных замечаний по рабочему раствору для других, новых для JSON Я добавил еще одно свойство для своего класса для Словаря, так как это действительно «unix-time-stamp-data», «Value». Это позволяет мне работать в C# с datetime/values. Возможно, лучший способ кастинга, но это работает, не вызывает заметных проблем с производительностью для моего сценария.
[JsonProperty("dps")]
public Dictionary<string, double> TimeValues { get; set; }
public List<TimeValue> DataPoints
{
get
{
List<TimeValue> times = new List<TimeValue>();
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
foreach (var item in TimeValues)
{
times.Add(new TimeValue
{
Time = dtDateTime.AddSeconds(double.Parse(item.Key)).ToLocalTime(),
Value = item.Value
});
}
return times;
}
}
Я обновил свой вопрос после того, как я попробовал ваше предложение. Разная ошибка, я изменил код, как вы ожидали? Благодарю. – John
Спасибо за обновленный пример, словарь отсортировал это для меня. –
John
Могу ли я использовать словарь для словаря , поскольку строки являются датами unix? –
John