是否有更改WCF中DateTime的默认JSON序列化/反序列化?
目前,DateTime被序列化为/Date(1372252162657+0200)/
格式,应该没问题,但是当我的服务器不是UTC(我无法更改)时,我遇到了问题。
此服务正在处理的所有日期/时间数据均为UTC格式。当服务器使用UTC时,一切正常。但是,staging / prod环境设置为GMT + 1(Paris),序列化器假设日期/时间是GMT + 1,完全忽略属性Kind
。因此,您希望调用DateTime.SetKind()
并将其设置为UTC将无法正常工作。实际上,序列化时间会延迟一个小时。
我可以进行双向日期对话(在反序列化时也做出相同的假设,因此它的GMT + 1总是)对话的日期:UTC到/从服务器时间,但这是乏味的。所以我想也许我可以覆盖默认的序列化行为。
答案 0 :(得分:20)
只是为了扩展 tdelepine 的代码段,这里是我使用过的代码:
在我的WCF JSON服务中,我有一个(可为空的)DateTime值,并希望我的服务以更易读的格式返回日期,因此我的iPhone应用程序将能够解释它。
在应用了一些更改之后,这就是我的JSON的样子:
注意UpdateDateOriginal
字段,它是WCF写入DateTimes的默认方式,以及我使用下面的代码创建的友好UpdateDate
字段。
我的原始线条看起来像这样:
[DataMember]
public DateTime? UpdateDateOriginal { get; set; }
...以下是创建新友好UpdateDate
JSON值的行。
[IgnoreDataMember]
public DateTime? UpdateDate { get; set; }
[DataMember(Name = "UpdateDate")]
private string UpdateDateString { get; set; }
[OnSerializing]
void OnSerializing(StreamingContext context)
{
if (this.UpdateDate == null)
this.UpdateDateString = "";
else
this.UpdateDateString = this.UpdateDate.Value.ToString("MMM/dd/yyyy HH:mm", CultureInfo.InvariantCulture);
}
[OnDeserialized]
void OnDeserializing(StreamingContext context)
{
if (this.UpdateDateString == null)
this.UpdateDate = null;
else
this.UpdateDate = DateTime.ParseExact(this.UpdateDateString, "MMM/dd/yyyy HH:mm", CultureInfo.InvariantCulture);
}
实际上,您可能会发现以ISO8601格式返回DateTime
值更有用。例如:
UpdateTime: "2014-08-24T13:02:32",
要执行此操作,只需使用上面的代码,但在两个位置都将字符串"MMM/dd/yyyy HH:mm"
更改为"s"
。
并且,如果您的DateTime值以UTC格式存储,但您希望WCF服务返回用户本地时区的值,则可以按照我的提示进行操作:
Get DateTime in users local timezone
通过一些简单的例子,生活不容易!
答案 1 :(得分:12)
您可以在json对象定义中使用此变通方法
[IgnoreDataMember]
public DateTime dateObject;
public string dateCustomSerialize
{
get {
//Custom get
}
set {
//Custom set
}
}
在评估中放置自定义格式序列化
答案 2 :(得分:4)
是的,可以使用名为“邮件格式化程序”
的概念来完成但是Message Formatter很难解决堆栈溢出问题。 你可以参考WCF Extensibility : Message Formatters
如果你不想搞砸这个,那么黑客就可以了。
将每个方法的返回类型设置为Stream。
e.g。
public Stream GetStaticData()
{
var objTobeReturned = something;
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
return new MemoryStream(Encoding.UTF8.GetBytes(objTobeReturned.ToJson()));
}
这里ToJson()是我自己的扩展方法,它使用NewtonSoft库将对象转换为json字符串。
WCF将跳过用于序列化的流输出,并将其原样传递给您的客户端。
我希望你得到答案。
答案 3 :(得分:0)
一种方法是使用邮件格式化程序更改默认DataContractSerializer
,如WCF Extensibility – Message Formatters中所述。
另一种选择是编写一个扩展方法,将对象加载到流中,然后可以将任何所需的序列化程序应用于该对象。有关如何执行此操作的详细信息,请参阅Replace default JSON serializer in WCF 4 to JSON.NET的已接受答案。
答案 4 :(得分:0)
这并不能解决你的时区问题,但是我会在这里发布给其他正在与WCF,ticks和DateTime进行斗争的人。
如果您不想要刻度,但需要人类可读的时间格式,则可以通过引入额外的string
属性来实现。然后,在将值转换为字符串之前,需要摆弄DateTime
。
[IgnoreDataMember] // Ignore the original tick date.
public DateTime LastReminderDate { get { return _lastReminderDate; } set { _lastReminderDate = value; } }
[DataMember] // Make sure you have a public or private setter!
public string LastReminderDateText { get { return _lastReminderDate.ToString(); } set { _lastReminderDate = DateTime.Parse(value); } }