Web Api 2 - custom data type JSON serialization

落爺英雄遲暮 提交于 2019-12-20 02:38:04

问题


I'm actually new to Web Api, so my question may sound a bit odd.

I have simple API to return historical information about price changes. My controller's action looks like this:

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

where PriceHistoryRecordModel is

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

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

However, the problem is - action returns JSON in following format

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

but, due to specific client requirements to data format, I need my JSON to look this way

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

So, I wonder

  • if there's a way to achieve such custom serialization?
  • can I wrap this custom serialization in an attribute and use it as an aspect?

回答1:


You can write a CustomConverter like this:

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);
        }
    }

Specify that our class is serialized by this converter:

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

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

It works, but it's kind of overhead if you only need this special treatment in this specific case.

In case you have many similar cases like this, you can have your classes implement a base class and use this converter for all these classes.

In this simple case, a quick solution is just to change your return type to double[]:

public async Task<IEnumerable<double[]>> GetHistory(string id, Size size)

And covert your datetime to a number by using DateTime.Ticks



来源:https://stackoverflow.com/questions/36233759/web-api-2-custom-data-type-json-serialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!