Json.NET IsoDateTimeConverter无法使用Stripe.NET库中的类



我使用的是ASP.NET Web API。我有以下代码,在序列化为JSON时,responseIEnumerable<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日期。

你有几个选择来解决这个问题:

  1. 最直接的选项是将发票数据从StripeInvoice复制到您自己的Invoice类版本,然后从Web API返回,而不是直接将StripeInvoice传递给消费者。老实说,这可能是您的最佳选择,因为它将数据源(Stripe)的关注点与您自己的API的关注点分离开来。您可能会使用AutoMapper之类的工具来帮助复制数据
  2. 当您在Web API中序列化Stripe.Net类时,应该可以创建一个自定义IContractResolver来动态地用IsoDateTimeConverter替换它们中的StripeDateTimeConverter(请参阅下面的更新)
  3. 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' }}

我希望这有助于指导方针解决这个问题。

相关内容

  • 没有找到相关文章

最新更新