Я относительно новичок в работе с данными C # и JSON и ищу руководства. Я использую C # 3.0, с .NET3.5SP1 и JSON.NET 3.5r6.
У меня есть определенный класс C #, который мне нужно заполнить из структуры JSON. Однако не каждая структура JSON для записи, получаемой из веб-службы, содержит все возможные атрибуты, определенные в классе C #.
Я делал то, что кажется неправильным, сложным способом, и просто выбирал каждое значение одно за другим из JObject и преобразовывал строку в желаемое свойство класса.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
Каков наилучший способ десериализации структуры JSON в класс C # и обработки возможных пропущенных данных из источника JSON?
Мой класс определяется как:
public class MyAccount
{
[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }
[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }
[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }
[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }
[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }
[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }
[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }
[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }
[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }
[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }
[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }
[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }
[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }
[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }
[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }
}
И пример JSON для разбора:
{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
источник
Вы пытались использовать универсальный метод DeserializeObject?
Любые пропущенные поля в данных JSON должны просто быть пустыми.
ОБНОВИТЬ:
Если строка JSON является массивом, попробуйте это:
jarray
должен бытьList<MyAccount>
.ДРУГОЕ ОБНОВЛЕНИЕ:
Исключение, которое вы получаете, не согласуется с массивом объектов - я думаю, что у сериализатора возникли проблемы с вашим типизированным по словарю
accountstatusmodifiedby
свойством.Попробуйте исключить
accountstatusmodifiedby
свойство из сериализации и посмотрите, поможет ли это. Если это произойдет, вам может потребоваться представить это свойство по-другому.Документация: Сериализация и десериализация JSON с Json.NET
источник
DateTime AccountStatusExpiration
(например) не обнуляется, как определено в коде. Что нужно сделать, чтобы сделать его обнуляемым? Просто поменятьDateTime
наDateTime?
?Вы можете использовать
dynamic
тип C #, чтобы упростить задачу. Этот метод также упрощает ре-факторинг, поскольку он не зависит от волшебных строк.Json
Приведенная
json
ниже строка представляет собой простой ответ на вызов HTTP API и определяет два свойства:Id
иName
.C #
Используйте
JsonConvert.DeserializeObject<dynamic>()
для десериализации этой строки в динамический тип, а затем просто получите доступ к ее свойствам обычным способом.Примечание . Ссылка NuGet для сборки NewtonSoft: http://nuget.org/packages/newtonsoft.json . Не забудьте добавить:
using Newtonsoft.Json;
для доступа к этим классам.источник
DeserializeObject<dynamic>
определению, не «проверен на тип». Таким образом, следующие строкиresults.Id
иresults.Name
не могут быть проверены во время компиляции. Любые ошибки будут возникать во время выполнения. Сравните это со строго типизированным вызовом, таким какDeserializeObject<List<MyAccount>>
. Ссылки на эти свойства могут быть подтверждены во время компиляции. Использованиеdynamic
, хотя это может быть удобно, вводит «волшебные строки» в качестве имен свойств; снижение надежности ИМХО.Ты можешь использовать:
здесь:
json
строка json,obj
целевой объект. См: примерПримечание:
PopulateObject()
не удалит данные списка obj, после тогоPopulate()
, какobj's
член списка будет содержать свои исходные данные и данные из строки jsonисточник
Опираясь на ответ bbant, это мое полное решение для десериализации JSON с удаленного URL.
Использование будет как:
Где
FeedResult
класс, сгенерированный с использованием Xamasoft JSON Class GeneratorВот снимок экрана с настройками, которые я использовал, учитывая странные имена свойств, которые веб-версия не может объяснить.
источник
Я нашел свой Я построил мой объект неправильно. Я использовал http://json2csharp.com/, чтобы сгенерировать свой класс объектов из JSON. Как только у меня был правильный Oject, я мог читать без проблем. Норбит, ошибка Нуба. Думаю, я добавлю это на случай, если у вас возникнет та же проблема.
источник
Вы можете попробовать проверить некоторые из генераторов классов онлайн для получения дополнительной информации. Тем не менее, я считаю, что некоторые ответы были полезны. Вот мой подход, который может быть полезен.
Следующий код был сделан с учетом динамического метода.
Этот код в основном позволяет получить доступ к членам, содержащимся в строке Json. Просто по-другому без необходимости занятий.
query
,trend
Иurl
являются объекты , содержащиеся в строке Json.Вы также можете использовать этот сайт . Не доверяйте классам на 100%, но вы поняли идею.
источник
Предполагая, что ваши примеры данных верны, ваше имя и другие записи, заключенные в квадратные скобки, являются массивами в JS ... вы захотите использовать List для этих типов данных. и список, скажем, accountstatusexpmaxdate ... Я думаю, что в вашем примере даты неверно отформатированы, хотя и неуверенно относительно того, что еще неверно в вашем примере.
Это старый пост, но хотелось бы отметить проблемы.
источник