У меня есть объект JSON, который я deserialized в объект на стороне сервера. Одним из объектов является аррайалист объектов, и каждый объект является словарем строки, массива. В моих часах я могу развернуть объекты и увидеть все, что находится в объекте, но я не могу понять, как получить доступ к данным внутри объектов в коде. Мне нужно пройти через каждый объект и получить доступ к ключам и значениям внутри словарей. Объект Rigor - это то, что я пытаюсь развернуть.
Я жестко закодировал пример того, как выглядят данные.
string rigorSelection = "{\"StandardID\":165638," +
"\"ItemTypes\":[\"Multiple Choice\",\"True/False\",\"Constructed Response\",\"Explicit Constructed Response\",\"Select Dropdown\",\"Evidence Based Selected Response\",\"Drag and Drop\",\"Selectable Text\",\"Multi-Part\",\"Graphing\",\"Matching\"], " +
"\"TotalItemCount\":10," +
"\"StandardName\":\"CCSS.9_12.MA.N.RN.2\"," +
"\"Rigor\":[" +
"{\"Remembering\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Understanding\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Applying\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Analyzing\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Evaluating\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Creating\":[0,0,0,0,0,0,0,0,0,0,0]}," +
"{\"Not Specified\":[0,0,0,0,0,0,0,0,0,0,0]}]" +
"}";
System.Web.Script.Serialization.JavaScriptSerializer jSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
AssessmentWCFVariables assessmentWCFVariable = jSerializer.Deserialize<AssessmentWCFVariables>(rigorSelection);
var rigorCounts = assessmentWCFVariable.Rigor;
Класс, в котором десериализуются данные, - это...
[Serializable]
[DataContract]
public class AssessmentWCFVariables
{
[DataMember]
public int StandardID { get; set; }
[DataMember]
public string StandardName { get; set; }
[DataMember]
public ArrayList ItemTypes { get; set; }
[DataMember]
public ArrayList Rigor { get; set; }
[DataMember]
public int TotalItemCount { get; set; }
}
UPDATE rigorCounts - это ArrayList объектов. Я могу зацикливаться, хотя каждый объект, но все, что я пытаюсь получить в парах Key/Value в словарях, дает мне ошибку. Я пытаюсь это сделать.
foreach (var rigor in rigorCounts)
{
var key = //code to get key of rigor i.e Remembering
var value = //code to get the arrary i.e. [0,0,0,0,0,0,0,0,0,0,0]
}
Мне нужно пройти через каждый объект и получить доступ к ключам и значениям внутри словарей.
Если вы рассматриваете объекты в ваших словарях объектов Rigor, вы должны изменить тип объекта Rigor:
[DataMember]
public List<Dictionary<string, Int32[]>> Rigor { get; set; }
Затем вы можете легко прокручивать каждый словарь в объекте Rigor со следующим кодом:
var rigorCounts = assessmentWCFVariable.Rigor;
foreach (Dictionary<string, Int32[]> rigorCountDict in rigorCounts)
{
foreach (KeyValuePair<string, Int32[]> kvpair in rigorCountDict)
{
string key = kvpair.Key; // e.g. "Remembering"
Int32[] value = kvpair.Value; // e.g. [0,0,0,0,0,0,0,0,0,0,0]
}
}
На всякий случай, если у вас нет возможности сменить ваши контракты на данные в список словарей, вы можете сделать следующее в исходном файле Rigor ArrayList:
foreach (Dictionary<string, object> rigorCountDict in rigorCounts)
{
foreach (KeyValuePair<string, object> kvpair in rigorCountDict)
{
string key = kvpair.Key; // e.g. "Remembering"
Int32[] value = (Int32[])((ArrayList)kvpair.Value).ToArray(typeof(Int32)); // e.g. [0,0,0,0,0,0,0,0,0,0,0]
}
}
Он менее изящный, чем первый пример, но он также работает.
rigor
являются переменными (т. Е. Иногда может существовать ключ Remembering
, иногда нет, а иногда что-то совершенно неожиданное), тогда это абсолютно правильный способ сделать это. Если они исправлены, то создание строго типизированного объекта, вероятно, чище.
Я согласен с тем, что отдельный класс Rigor - лучший способ сделать это. Но чтобы ответить на ваш конкретный вопрос:
foreach (var item in assessmentWCFVariable.Rigor)
{
var dictionary = item as Dictionary<string, int[]>;
if (dictionary == null) continue;
// Do what you want with the dictionary here
}
Возможно, в AssesmentClass необходимо внести следующие изменения:
[DataMember]
public IEnumerable<Dictionary<string, int[]> Rigor { get; set; }
Вы используете ArrayList
для Rigor
. Когда вы получаете доступ к этому (например, по индексу), вы получите объект, который необходимо выполнить, прежде чем вы сможете получить доступ к его свойствам. Вероятно, было бы лучше создать класс для объектов Rigor
и использовать List<Rigor>
. Что-то вроде:
public class Rigor
{
public List<int> Remembering { get; set; }
public List<int> Understanding {get; set; }
// an so on for other properties...
}
А затем измените свой параметр AssessmentWCFVariables
чтобы:
[DataMember]
public List<Rigor> Rigor { get; set; }
ИМХО: нет оснований когда-либо использовать ArrayList
с момента введения общего List<T>