Я возвращаю XML из Rails API, но при попытке десериализации он продолжает получать ошибку «Строка» не является допустимым значением AllXsd. »Как десериализировать нулевое datetime из Rails-XML в C# «Строка '' не является допустимым значением AllXsd."
Я чувствую, что это должно быть очень просто и тривиально и что я просто пропускаю тот или иной атрибут, связанный с XML, но я не нахожу ничего, когда смотрю на google. Все примеры там, кажется, используют строку для значения Date-Time, а затем выполняют внутренний синтаксический анализ, чтобы получить фактическое значение DateTime с нулевым значением. Это будет работать, но будет беспорядочно и, вероятно, будет выглядеть странно в следующий раз, когда кто-то его увидит, и в этот момент они, вероятно, попытаются заменить его простым свойством и либо пропустить нуль во время тестирования, либо застрять там, где я сейчас.
Простите многословие следующего примера, но я попытался уменьшить его до наименьшего количества связанного кода из нашей реальной реализации.
class Program
{
static void Main(string[] args)
{
var samples = new Dictionary<string, DateTime?>{
{ // from Rails with populated datetime value
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<response>\r\n <latest-playing-at type=\"datetime\">2016-07-22T15:24:22+00:00</latest-playing-at>\r\n</response>\r\n"
,new DateTime(2016,07,22,17,24,22,DateTimeKind.Local)},
{ // from Rails with nil datetime value (THIS IS THE CASE I CARE ABOUT)
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<response>\r\n <latest-playing-at nil=\"true\"/>\r\n</response>\r\n"
,(DateTime?)null},
{ // (Test) Serialized from dotnet with null value
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<response xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <latest-playing-at xsi:nil=\"true\" />\r\n</response>"
,(DateTime?)null},
};
foreach (var sample in samples)
{
var xml = sample.Key;
var expected = sample.Value;
try
{
var testClass = DeserializeFromString<TestClass>(xml);
Console.WriteLine("Expected/Actual : {0}/{1}", expected, testClass.LatestPlayingAt);
Console.WriteLine(
DateTime.Equals(expected, testClass.LatestPlayingAt) ? "OK" : "Different" // ok to be different depening on time zones
);
}
catch (Exception exc)
{
Console.WriteLine("Error: {0}", exc.Message);
Console.WriteLine(exc);
}
}
Console.ReadKey(true);
}
public static T DeserializeFromString<T>(string inputXML)
{
using (MemoryStream inStream = new MemoryStream(new UTF8Encoding(false).GetBytes(inputXML)))
{
T result = DeserializeFromStream<T>(inStream);
return result;
}
}
public static T DeserializeFromStream<T>(Stream inStream)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(inStream);
}
}
[XmlRoot("response")]
public class TestClass
{
//[XmlElement("latest-playing-at")] // The string '' is not a valid AllXsd value.
//[XmlElement("latest-playing-at", Type = typeof(DateTime?))] // The string '' is not a valid AllXsd value.
//[XmlElement("latest-playing-at", Type = typeof(DateTime?), IsNullable = true)] // The string '' is not a valid AllXsd value.
//[XmlElement("latest-playing-at", Type = typeof(Nullable<DateTime>), IsNullable = true, Form = XmlSchemaForm.None)] // The string '' is not a valid AllXsd value.
[XmlElement("latest-playing-at", Type = typeof(Nullable<DateTime>), IsNullable = true, Form = XmlSchemaForm.Unqualified)] // The string '' is not a valid AllXsd value.
public DateTime? LatestPlayingAt { get; set; }
}