将代码从WCF迁移到Web API时的日期问题

时间:2013-10-29 07:58:34

标签: json asp.net-mvc-4 datetime asp.net-web-api datetimeoffset

我正在开发一个过去使用WCF工作的iOS应用程序。 我们正在更改此产品以使用MVC Web API而不是WCF。 我正面临着约会的问题!它们必须是像JCH格式一样的

 /Date(1373476260000-0600)/

但实际上返回的是这种格式

/Date(1379484000000)/
iOS控制器不接受

并生成默认日期值(如果它为null并且只是将其初始化为默认值(12/31/1969))

我试图将日期解析为所需的JSON格式日期字符串,但它导致了一个异常,因为它期待一个DateTime对象。

我还尝试添加以下行:

GlobalConfiguration.Configuration.Formatters.JsonFormatter. SerializerSettings.DateParseHandling = Newtonsoft.Json.DateParseHandling.DateTimeOffset;

到WebApiConfig.cs文件,但它不起作用,然后我尝试将它添加到AttributeRoutingHttpConfig.cs文件,然后添加到Global.asax但没有响应!

然后我试过了:

    var appXmlType = GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

还将它们添加到上面提到的3个文件中,但它没有用!

任何想法如何解决这个问题?

P.S:我只能访问Web API代码!我无法改变iOS代码!

感谢。

2 个答案:

答案 0 :(得分:1)

首先,请确保您已设置:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
    .DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;

否则,您将获得ISO8601格式而不是Microsoft格式。 (ISO8601 很多更好,但你说你不能改变iOS应用程序。)

然后,您需要意识到,对于DateTime值,.Kind会影响序列化的工作方式。如果您有DateTimeKind.Utc,那么它将不包含偏移量,因为这是特定格式的工作方式。

如果要确保始终生成偏移量,请改用DateTimeOffset值。这将为UTC提供+0000的偏移量。

例如:

var settings = new JsonSerializerSettings
                {
                    DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
                };

var dt = DateTimeOffset.UtcNow;
var json = JsonConvert.SerializeObject(dt, settings);
Debug.WriteLine(json); // "\/Date(1383153418477+0000)\/"

但是你需要非常小心这种方法,所有消费者都要尊重这种偏差。例如,如果客户端收到此消息并使用WCF的DateTime将其解析为DataContractJsonSerializer,则会出现一个已知错误,任何偏移量将被视为当地时间接收计算机,无论该偏移的实际值是多少。

如果可能,您应该切换服务器和应用程序以改为使用ISO8601格式。

答案 1 :(得分:0)

似乎日期的时区部分丢失了 - 尝试在WebApiConfig中设置:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;