Stack Overflow на русском Asked on December 25, 2021
Есть некий xml. Примерно такой:
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersResponse
xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2020-07-23T17:25:06.492Z</Timestamp>
<OrderArray>
<Order>
<OrderID>0000000000-111111111111</OrderID>
<OrderStatus>Completed</OrderStatus>
<CreatedTime>2020-07-22T07:09:19.000Z</CreatedTime>
</Order>
</GetOrdersResponse>
Преобразовав это дело в классы C# имею примерно это:
// Примечание. Для запуска созданного кода может потребоваться NET Framework версии 4.5 или более поздней версии и .NET Core или Standard версии 2.0 или более поздней.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:ebay:apis:eBLBaseComponents")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:ebay:apis:eBLBaseComponents", IsNullable = false)]
public partial class GetOrdersResponse
{
private DateTime timestampField;
private GetOrdersResponseOrderArray orderArrayField;
/// <remarks/>
public GetOrdersResponseOrderArray OrderArray
{
get
{
return this.orderArrayField;
}
set
{
this.orderArrayField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType = "date")]
public DateTime Timestamp
{
get
{
return this.timestampField;
}
set
{
this.timestampField = value;
}
}
}
Разумеется, классы автоматически сгенерированы.
И проблема заключается в том, что при запуске такого кода и попытке десериализации xml, я получаю исключение String "2020-07-23T17:25:06.492Z" was not recognized as a valid DateTime.
Начитавшись в интернетах всяких советов, я изменил мой C# класс следующим образом:
// Примечание. Для запуска созданного кода может потребоваться NET Framework версии 4.5 или более поздней версии и .NET Core или Standard версии 2.0 или более поздней.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:ebay:apis:eBLBaseComponents")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:ebay:apis:eBLBaseComponents", IsNullable = false)]
public partial class GetOrdersResponse
{
//[XmlAttribute(AttributeName = "Timestamp")]
//[XmlAttribute("Timestamp")]
//[SoapAttribute(DataType = "string", AttributeName = "Timestamp")]
// Ни одна из строк выше не помогла
private string timestampField; // пробовал ещё это поле
// делать public и приписать { get; set; } - тот же результат
private GetOrdersResponseOrderArray orderArrayField;
/// <remarks/>
public GetOrdersResponseOrderArray OrderArray
{
get
{
return this.orderArrayField;
}
set
{
this.orderArrayField = value;
}
}
/// <remarks/>
//[System.Xml.Serialization.XmlElementAttribute(DataType = "date")]
[XmlIgnore]
public System.DateTime Timestamp
{
get
{
if (string.IsNullOrEmpty(this.timestampField))
{
return new DateTime();
}
else
{
return DateTime.ParseExact(this.timestampField, "yyyy-MM-ddTHH:mm:ss.fffZ", System.Globalization.CultureInfo.InvariantCulture);
}
}
set
{
this.timestampField = value.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
}
}
Результат моих стараний – timestampField
всегда null. Если я менял timestampField
на Timestamp
и убирал все XmlAttribute
, то строка приходила правильная. Выходит, при использовании XmlAttribute
у меня всегда возвращается null. И вот тут я уже не имею представления, почему так происходит, и как это решить
P.S. В Order
(а также классах, что не попали в данный вопрос) с датой-временем ровно та же беда
UPD: На всякий случай также приложу метод, вызываемый при десериализации:
public object ConvertXMLStringToObject(Type typeForConverter, string text)
{
try
{
var xdoc = XDocument.Parse(text);
XmlSerializer s = new XmlSerializer(typeForConverter);
return s.Deserialize(xdoc.CreateReader());
}
catch
{
return null;
}
}
Вызывается данный метод такой строкой:
var result = (GetOrdersResponse)new XMLConverter().ConvertXMLStringToObject(typeof(GetOrdersResponse), await response.Content.ReadAsStringAsync());
Я сгенерировал в Студии код по представленному xml. Он отличается от вашего только отсутствием атрибута [System.Xml.Serialization.XmlElementAttribute(DataType = "date")]
на свойстве Timestamp
.
Просто уберите этот атрибут. В нём явно указано, что ожидается тип "date" - только дата, без времени.
Откуда мог взяться этот атрибут?
Вероятно, вы использовали другой xml при генерации, в котором не было времени в элементе Timestamp.
Другая возможная причина: генераторы классов по xml/json вполне могут ошибаться и генерировать не совсем валидный код. Поэтому ручная корректировка вполне допустима. Точный результат может обеспечить только генерация по схеме (XmlSchema), в который прописаны все типы данных.
Answered by Alexander Petrov on December 25, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP