Pur*_*ome 21 .net xml-serialization
DateTimeOffset当数据表示为Xml时,我在此类中拥有的属性不会被呈现.我需要做什么来告诉Xml序列化将其正确呈现为DateTime或DateTimeOffset?
[XmlRoot("playersConnected")]
public class PlayersConnectedViewData
{
[XmlElement("playerConnected")]
public PlayersConnectedItem[] playersConnected { get; set; }
}
[XmlRoot("playersConnected")]
public class PlayersConnectedItem
{
public string name { get; set; }
public DateTimeOffset connectedOn { get; set; } // <-- This property fails.
public string server { get; set; }
public string gameType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和一些样本数据......
<?xml version="1.0" encoding="utf-8"?>
<playersConnected
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<playerConnected>
<name>jollyroger1000</name>
<connectedOn />
<server>log1</server>
<gameType>Battlefield 2</gameType>
</playerConnected>
</playersConnected>
Run Code Online (Sandbox Code Playgroud)
我希望可能有一种方法通过属性,我可以在属性上装饰......
有没有办法摆脱根节点中声明的那两个命名空间?我是不是该?
Pet*_*ter 26
这是晚了几年,但这是使用ISO 8601 完全序列化的快速简便方法DateTimeOffset:
[XmlElement("lastUpdatedTime")]
public string lastUpdatedTimeForXml // format: 2011-11-11T15:05:46.4733406+01:00
{
get { return lastUpdatedTime.ToString("o"); } // o = yyyy-MM-ddTHH:mm:ss.fffffffzzz
set { lastUpdatedTime = DateTimeOffset.Parse(value); }
}
[XmlIgnore]
public DateTimeOffset lastUpdatedTime;
Run Code Online (Sandbox Code Playgroud)
And*_*Dog 14
我想出了这个结构,它实现了基于ISO 8601格式化的XML序列化(例如2011-11-11T15:05:46.4733406+01:00).提示:尝试按预期解析失败DateTime等值2011-11-11T15:05:46.
欢迎反馈.我没有在这里包含单元测试,因为那将是太多的文本.
/// <remarks>
/// The default value is <c>DateTimeOffset.MinValue</c>. This is a value
/// type and has the same hash code as <c>DateTimeOffset</c>! Implicit
/// assignment from <c>DateTime</c> is neither implemented nor desirable!
/// </remarks>
public struct Iso8601SerializableDateTimeOffset : IXmlSerializable
{
private DateTimeOffset value;
public Iso8601SerializableDateTimeOffset(DateTimeOffset value)
{
this.value = value;
}
public static implicit operator Iso8601SerializableDateTimeOffset(DateTimeOffset value)
{
return new Iso8601SerializableDateTimeOffset(value);
}
public static implicit operator DateTimeOffset(Iso8601SerializableDateTimeOffset instance)
{
return instance.value;
}
public static bool operator ==(Iso8601SerializableDateTimeOffset a, Iso8601SerializableDateTimeOffset b)
{
return a.value == b.value;
}
public static bool operator !=(Iso8601SerializableDateTimeOffset a, Iso8601SerializableDateTimeOffset b)
{
return a.value != b.value;
}
public static bool operator <(Iso8601SerializableDateTimeOffset a, Iso8601SerializableDateTimeOffset b)
{
return a.value < b.value;
}
public static bool operator >(Iso8601SerializableDateTimeOffset a, Iso8601SerializableDateTimeOffset b)
{
return a.value > b.value;
}
public override bool Equals(object o)
{
if(o is Iso8601SerializableDateTimeOffset)
return value.Equals(((Iso8601SerializableDateTimeOffset)o).value);
else if(o is DateTimeOffset)
return value.Equals((DateTimeOffset)o);
else
return false;
}
public override int GetHashCode()
{
return value.GetHashCode();
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
var text = reader.ReadElementString();
value = DateTimeOffset.ParseExact(text, format: "o", formatProvider: null);
}
public override string ToString()
{
return value.ToString(format: "o");
}
public string ToString(string format)
{
return value.ToString(format);
}
public void WriteXml(XmlWriter writer)
{
writer.WriteString(value.ToString(format: "o"));
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我也不确定最好的方法,但这就是我做的:
[XmlElement("lastUpdatedTime")]
public string lastUpdatedTimeForXml
{
get { return lastUpdatedTime.ToString(); }
set { lastUpdatedTime = DateTimeOffset.Parse(value); }
}
[XmlIgnore]
public DateTimeOffset lastUpdatedTime;
Run Code Online (Sandbox Code Playgroud)
我最终只是这样做了......
public static double ToUnixEpoch(this DateTimeOffset value)
{
// Create Timespan by subtracting the value provided from
//the Unix Epoch then return the total seconds (which is a UNIX timestamp)
return (double)((value - new DateTime(1970, 1, 1, 0, 0, 0, 0)
.ToLocalTime())).TotalSeconds;
}
public static string ToJsonString(this DateTimeOffset value)
{
return string.Format("\\/Date({0})\\/", value.ToUnixEpoch());
}
Run Code Online (Sandbox Code Playgroud)
[XmlRoot("playersConnected")]
public class PlayersConnectedItem
{
public string name { get; set; }
public string connectedOn { get; set; }
public string server { get; set; }
public string gameType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
var data = (from q in connectedPlayerLogEntries
select new PlayersConnectedItem
{
name = q.ClientName,
connectedOn = q.CreatedOn.ToJsonString(),
server = q.GameFile.UniqueName,
gameType = q.GameFile.GameType.Description()
});
Run Code Online (Sandbox Code Playgroud)
完毕。不确定这是否是最好的方法..但现在 viewdata 属性对于 Json 或 Xml 具有相同的值。