使用Attributes和ServiceStack.Text.JsonSerializer进行自定义序列化

时间:2016-05-26 10:08:26

标签: c# json servicestack servicestack-text

我们使用自定义属性来注释数据的显示方式:

public class DcStatus
{
    [Format("{0:0.0} V")]   public Double Voltage { get; set; }
    [Format("{0:0.000} A")] public Double Current { get; set; }
    [Format("{0:0} W")]     public Double Power => Voltage * Current;
}

使用属性提供的格式使用String.Format处理属性。

我们如何配置ServiceStack.Text.JsonSerializer以使用该属性呢?

示例:

var test = new DcStatus {Voltage = 10, Current = 1.2};
var json = JsonSerializer.SerializeToString(test);

应该产生

{
    "Voltage": "10.0 V",
    "Current": "1.200 A",
    "Power"  : "12 W",
}

1 个答案:

答案 0 :(得分:4)

没有可自定义的回调,允许您根据自定义属性属性修改内置类型的序列化方式。

为此类型获取所需的自定义序列化的一个选项是实现ServiceStack.Text使用的ToJson()方法,例如:

public class DcStatus
{
    [Format("{0:0.0} V")]
    public Double Voltage { get; set; }
    [Format("{0:0.000} A")]
    public Double Current { get; set; }
    [Format("{0:0} W")]
    public Double Power => Voltage * Current;

    public string ToJson()
    {
        return new Dictionary<string,string>
        {
            { "Voltage", "{0:0.0} V".Fmt(Voltage) },
            { "Current", "{0:0.000} A".Fmt(Current) },
            { "Power", "{0:0} W".Fmt(Power) },
        }.ToJson();
    }
}

打印出所需的结果:

var test = new DcStatus { Voltage = 10, Current = 1.2 };
test.ToJson().Print(); //= {"Voltage":"10.0 V","Current":"1.200 A","Power":"12 W"}

否则,如果您不想更改现有的Type,您还可以通过注册JsConfig<T>.RawSerializeFn impl并返回您想要使用的自定义JSON来自定义现有类型的序列化,例如:

 JsConfig<DcStatus2>.RawSerializeFn = o => new Dictionary<string, string> {
    { "Voltage", "{0:0.0} V".Fmt(o.Voltage) },
    { "Current", "{0:0.000} A".Fmt(o.Current) },
    { "Power", "{0:0} W".Fmt(o.Power) },
}.ToJson();