JSON.NET:如何在序列化之前执行对象的隐式转换



我有一个具有许多'可选bools'的类 - 可能是真实,false或null的布尔值。在.NET中表示这一点的最常见方法是使用bool?,但是在内存中至少占用了2个字节(请参阅此问题),因此我编写了自己的OptionalBool struct,该结构仅占1个字节,并且隐含地可转换为bool?

我的问题是,我有这样的课:

public class PartnerLoginOptions
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string DeviceModel { get; set; }
    public string Version { get; set; }
    public OptionalBool IncludeUrls { get; set; }
    public OptionalBool ReturnDeviceType { get; set; }
    public OptionalBool ReturnUpdatePromptVersions { get; set; }
}

在序列化时,如何使json.net执行从OptionalBoolbool?的Implcit转换?例如,如果 IncludeUrlsdefault(OptionalBool)('null'),则 ReturnDeviceType为true, ReturnUpdatePromptVersions是错误的,那么输出的JSON看起来像

{
    "includeUrls": null,
    "returnDeviceType": true,
    "returnUpdatePromptVersions": false
}

我该如何给定一个PartnerLoginOptions对象?我到目前为止的代码是

var body = JsonConvert.SerializeObject(options, new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

编辑:如果有用,这是OptionalBool的源代码。

回答您的问题,您可以执行以下操作:

public class PartnerLoginOptions
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string DeviceModel { get; set; }
    public string Version { get; set; }
    [JsonIgnore]
    public OptionalBool IncludeUrls { get; set; }
    [JsonProperty("IncludeUrls")]
    public bool? IncludeUrlsConverted 
    { 
        get { return (bool?)IncludeUrls; } // your conversion here
        set { IncludeUrls = (OptionalBool)value; } // your backwards conversion here
    }
}

或者您可以编写自己的JsonConverter

但是,对我来说,您的OptionalBool似乎是一种过度工程。2个字节绝对不是什么,我无法想象当它真正需要时,虽然它会产生如此多的不兼容问题,产生转换器和不同的骇客,并降低可读性。
考虑更改为bool?

如果您真的想这样做,则可以为OptionalBool定义自定义转换器:

public class OptionalBoolConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(OptionalBool) == objectType;
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var converted = (bool?) (OptionalBool) value;
        writer.WriteValue(converted);
    }
}

然后以这种方式使用:

var test = new PartnerLoginOptions
        {
            ReturnDeviceType = true,
            ReturnUpdatePromptVersions = false
        };
        var json = JsonConvert.SerializeObject(test, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new JsonConverter[] {new OptionalBoolConverter()}
        });

相关内容

  • 没有找到相关文章

最新更新