Ответ 1
Вы можете создать JsonReader из JToken.
JsonReader reader = token.CreateReader();
Мне дан поток данных json, который содержит поле с именем "type". Это поле типа описывает тип объекта, который необходимо создать во время выполнения. Похоже, что я не могу использовать JsonTextReader дважды, и я не могу найти в reset текстовый редактор в начале.
using (var streamReader = new StreamReader(stream, Encoding))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
JToken token = JObject.Load(jsonTextReader);
var type = (string) token.SelectToken("type");
var modelType = Type.GetType("Project." + type + ", Project");
// Fails here
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
Я получаю это сообщение об ошибке. Неожиданный токен при десериализации объекта: EndObject.
Вы можете создать JsonReader из JToken.
JsonReader reader = token.CreateReader();
Чтобы reset ваш читатель вначале, установите для свойства Position базового потока значение 0.
streamReader.BaseStream.Position = 0;
Изменить: Хотя это будет reset ваш базовый поток, jsonTextReader имеет только для прямого доступа по определению, что означает, что его номер строки и позиция отображаются только в режиме чтения. Для этого вам нужно будет reset positionReader, а затем передать его в объект new JsonTextReader.
Итак, к сожалению, у Фила нет возможности читать JsonTextReader дважды, потому что он доступен только для переходов.
Ссылка: http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm "Представляет читателя, который обеспечивает быстрый, не кэшированный, прямой доступ к последовательным данным Json".
Я провел еще несколько тестов и обнаружил, что работает следующее.
JsonTextReader.CloseInput = false
JsonTextReader
(закрыв оператор using
)StreamReader.BaseStream.Position = 0
JsonTextReader
Он будет выглядеть примерно так:
using (var streamReader = new StreamReader(stream, encoding))
{
Type modelType = null;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
jsonTextReader.CloseInput = false;
JToken token = JObject.Load(jsonTextReader);
string type = (string)token.SelectToken("type");
modelType = Type.GetType("Project." + type + ", Project");
}
streamReader.BaseStream.Position = 0;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
}
Я использую JsonTextReader
в эффективном для памяти формате, избегая кучи больших объектов и т.д. в моем блоге, так как за рекомендации Джеймса Ньютона Кинга. Вы можете использовать это и прилагаемый код для чтения своего JSON несколько раз, не беспокоясь о базовой реализации JsonTextReader
.
Комментарии и отзывы всегда приветствуются.