Консольное приложение на С#
Со стороннего сайта получаю json в формате json5:
[{
contentId: 'f1654c004d0207fab3f1f30d9d5f7b1a',
date: new Date('05/14/2018 10:50:00')
},
{
contentId: 'f1954d004d0287fab3f2f30d9d5f7b1a',
date: new Date('08/24/2018 10:50:00')
},
...
]
Хранится в строковой переменной.
Вопрос в том какие варианты работы есть с таким существом в C#??
Что пробовал:
Подключить библиотеку JSON5 .NET. Не работает, не компилируется, написано что билд сломан
Пройти регуляркой, остановился на проблеме полей с new Date: вот тут
Ответ
Вам может помочь Json.Net от Newtonsoft с кастомным конвертером даты.
Вообще, если гуглить does json.net support json5 мы сразу выходим на то, что поддержка ("большей части" - май 2017 года) уже есть. Но действительно, такие даты как у вас не поддерживаются.
Странный у вас вообще формат времени. Официальная спецификация json5 вообще ничего не говорит о формате времени, это оставлено на откуп спецификациям на Javascript:
JSON itself does not specify how dates should be represented, but
JavaScript does.
There is no right format; The JSON specification does not specify a
format for exchanging dates which is why there are so many different
ways to do it.
The best format is arguably a date represented in ISO 8601 format (
(См. тут: The “right” JSON date format)
Но... у вас не ISO 8601 даты... у вас вообще в вопросе одни строки, а по ссылке с регуляркой другие (и подозреваю, что там правильно: формат MM/DD/YYYY HH:MM:SS).
В принципе, должно помочь написание кастомного конвертера, чего-то типа JavaScriptDateTimeConverter - вот например, очень похожий пример
Я не знаю, все ли даты приходят в таком формате, не знаю, насколько этот гос. сайт специфицирует такой формат (или может неожиданно перейти на ИСО 8601 - 2001 и поломать вам код), но в принципе, можно написать свой конвертер, обложить для надёжности юнит-тестами и тогда уже использовать в продакшене.
Вот вам рабочий приме для основы:
void Main()
{
var source = @"[
{
contentId: 'f1654c004d0207fab3f1f30d9d5f7b1a',
date: new Date('05/14/2018 10:50:00')
},
{
contentId: 'f1954d004d0287fab3f2f30d9d5f7b1a',
date: new Date('05/14/2018 17:43:05')
}]";
var parsed = Newtonsoft.Json.JsonConvert.DeserializeObject
public class SomeClass
{
public string contentId { get; set; }
[JsonConverter(typeof(JavaScriptGovSiteDateTimeConverter))]
public DateTime date { get; set; }
}
public class JavaScriptGovSiteDateTimeConverter : JavaScriptDateTimeConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Type type = (Nullable.GetUnderlyingType(objectType) ?? objectType);
bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);
var token = JToken.Load(reader);
if (token == null || token.Type == JTokenType.Null)
{
if (!isNullable)
throw new JsonSerializationException(string.Format("Null value for type {0} at path {1}", objectType.Name, reader.Path));
return null;
}
if (token.Type != JTokenType.Constructor)
{
throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path));
}
var constructor = (JConstructor)token;
if (!string.Equals(constructor.Name, "Date", StringComparison.Ordinal))
{
throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path));
}
var values = constructor.Values().ToArray();
if (values.Length == 0)
{
throw new JsonSerializationException(string.Format("Invalid Date constructor \"{0}\" at path {1}", token.ToString(), reader.Path));
}
else if (values.Length == 1)
{
DateTime dt;
if (!DateTime.TryParseExact(values[0].ToString(), "MM/dd/yyyy H:m:s", null, DateTimeStyles.None, out dt))
throw new Exception("date format is not MM/dd/yyyy H:m:s");
return dt;
}
else
{
throw new Exception("Вот сейчас прям совсем неожиданно было");
}
}
}
Комментариев нет:
Отправить комментарий