簡體   English   中英

Json.NET:如何在序列化之前執行對象的隱式轉換?

[英]Json.NET: How to perform implicit conversion of an object before serializing?

我有一個包含很多“可選布爾值”的類-布爾值,它們可能為true,false或null。 在.NET中最常見的表示方法是使用bool? ,但是占用內存至少2個字節(請參閱此問題 ),因此我編寫了自己的OptionalBool結構,該結構僅占用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?的隱式轉換bool? 在序列化時? 例如,如果IncludeUrlsdefault(OptionalBool) (為'null'), ReturnDeviceType為true, ReturnUpdatePromptVersions為false,則輸出的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字節絕對不多,我無法想象真正需要它的情況,盡管它會造成很多不兼容問題,產生轉換器和不同的hack,並降低了可讀性。
考慮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()}
        });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM