【问题标题】:Web Api 2 - custom data type JSON serializationWeb Api 2 - 自定义数据类型 JSON 序列化
【发布时间】:2016-03-26 09:36:37
【问题描述】:

我实际上是 Web Api 的新手,所以我的问题可能听起来有点奇怪。

我有简单的 API 来返回有关价格变化的历史信息。我的控制器的操作如下所示:

[HttpGet]
[Route("api/history/{id}/{size}")]
public async Task<IEnumerable<PriceHistoryRecordModel>> GetHistory(string id, Size size)

PriceHistoryRecordModel 在哪里

[DataContract]
public class PriceHistoryRecordModel
{
    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public double Value { get; set; }
}

但是,问题是 - 操作返回以下格式的 JSON

[{"Date":"2016-02-07T08:22:46.212Z","Value":17.48},{"Date":"2016-02-08T09:34:01.212Z","Value":18.37}]

但是,由于客户对数据格式的特定要求,我需要我的 JSON 以这种方式显示

[[1238371200000,17.48],[1238457600000,18.37]]

所以,我想知道

  • 是否有办法实现这种自定义序列化?
  • 我可以将此自定义序列化包装在属性中并将其用作方面吗?

【问题讨论】:

  • 尝试将您的返回类型更改为double[]:public async Task&lt;IEnumerable&lt;double[]&gt;&gt; GetHistory(string id, Size size)。并使用DateTime.Millisecond 将您的日期时间转换为一个数字
  • @KhanhTO 谢谢,这有效并解决了眼前的问题。但是,自定义序列化的问题仍然存在。

标签: c# json serialization asp.net-web-api2


【解决方案1】:

你可以这样写CustomConverter

public class CustomCoverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            PriceHistoryRecordModel obj = value as PriceHistoryRecordModel;
            JToken t = JToken.FromObject(new double[] { obj.Date.Ticks, obj.Value });
            t.WriteTo(writer);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override bool CanConvert(Type objectType)
        {
            return typeof(PriceHistoryRecordModel).IsAssignableFrom(objectType);
        }
    }

指定我们的类被这个转换器序列化:

[JsonConverter(typeof(CustomCoverter))]
[DataContract]
public class PriceHistoryRecordModel
{
    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public double Value { get; set; }
}

它可以工作,但如果您只在这种特定情况下需要这种特殊处理,那就有点开销了。

如果你有很多类似的情况,你可以让你的类实现一个基类并将这个转换器用于所有这些类。

在这种简单的情况下,一个快速的解决方案就是将您的返回类型更改为double[]

public async Task&lt;IEnumerable&lt;double[]&gt;&gt; GetHistory(string id, Size size)

并使用 DateTime.Ticks 将您的日期时间转换为数字

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2012-08-29
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多