我使用的是ASP.NET Web API。我有以下代码,在序列化为JSON时,response
IEnumerable<StripeInvoice>
中的日期没有转换为ISO8601格式。它们采用类似于/Date(1412657602)/
的Microsoft.NET格式。使用IsoDateTimeConverter()
应转换为ISO 8601格式,如2011-07-14T19:43:37+0100
。为什么这不适用于IEnumerable<StripeInvoice>
?
IEnumerable<StripeInvoice> response = service.List();
string json = JsonConvert.SerializeObject(response, new IsoDateTimeConverter());
编辑
这是我的Web API控制器的完整方法。
public IEnumerable<StripeInvoice> GetUserInvoices(string id)
{
var options = new StripeInvoiceListOptions()
{
CustomerId = id
};
// Using https://github.com/jaymedavis/stripe.net stripe library
var invoiceService = new StripeInvoiceService();
invoiceService.ApiKey = "key";
IEnumerable<StripeInvoice> response = invoiceService.List(options);
// test
IEnumerable<SomeObject> objs = new SomeObject[] {
new SomeObject() { SomeDate = DateTime.Now.AddDays(-1) },
new SomeObject() { SomeDate = DateTime.Now }
};
// return objs; // this serialized the dates properly into ISO 8601
return response; // this doesn't serialize to ISO 8601. It remains in /Date(142657602)/
}
问题是Stripe.Net库中的StripeInvoice
类标记有[JsonConverter]
属性,因此所有DateTime
属性都使用StripeDateTimeConverter
。该转换器总是以/Date(1412657602)/
的形式写出日期,正如您在源代码中看到的那样。据推测,这是为了允许类与Stripe REST API正确工作,后者显然不使用ISO 8601日期。
你有几个选择来解决这个问题:
- 最直接的选项是将发票数据从
StripeInvoice
复制到您自己的Invoice
类版本,然后从Web API返回,而不是直接将StripeInvoice
传递给消费者。老实说,这可能是您的最佳选择,因为它将数据源(Stripe)的关注点与您自己的API的关注点分离开来。您可能会使用AutoMapper之类的工具来帮助复制数据 - 当您在Web API中序列化Stripe.Net类时,应该可以创建一个自定义
IContractResolver
来动态地用IsoDateTimeConverter
替换它们中的StripeDateTimeConverter
(请参阅下面的更新) - Stripe.Net库是开源的;您可以根据自己的需要修改代码,以便根据上下文打开或关闭
StripeDateTimeConverter
。这可以说是三种选择中最糟糕的一种,因为每次更新库时,都必须重新应用自定义更改
更新
如果你对第二种方法感兴趣,这里有一个合同解析器的可能实现:
class ForceIsoDateTimeResolver : DefaultContractResolver
{
private JsonConverter dateConverter = new IsoDateTimeConverter();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
// For any DateTime property on any class, replace the
// existing converter with an IsoDateTimeConverter.
if (prop.PropertyType == typeof(DateTime) ||
prop.PropertyType == typeof(DateTime?))
{
prop.Converter = dateConverter;
}
return prop;
}
}
要将此冲突解决程序安装到Web API项目中,请将以下内容添加到WebApiConfig
类的Register
方法中(在Web API项目的App_Start
文件夹中):
JsonSerializerSettings settings = config.Formatters.JsonFormatter.SerializerSettings;
settings.ContractResolver = new ForceIsoDateTimeResolver();
我也遇到了同样的问题,但我通过从/Date(…)/中获取unix时间并将该值乘以一千来解决了这个问题最后使用angular的日期函数,就像这个代码一样。
{{(x.created | limitTo : 10 : 6) * 1000 | date: 'yyyy-MM-dd HH:mm:ss Z' }}
我希望这有助于指导方针解决这个问题。