Как мне сериализовать объект, подобный единственному типу объединения C #, к его базовому значению и обратно?

Я моделирую домен, и для нескольких выбранных свойств, хотя их значения просты, я не хочу использовать встроенный интеграл (например, int ) или очень общий тип (например, System.Guid ).

Поэтому я ввел несколько простых типов «обёрток». В сочетании с неявными операторами я доволен результатом:

class Order
{
    public Price Price { get; set; }
}

order.Price = 4.95m;

Где Price «оборачивает» decimal и сохраняет значение в закрытом поле с именем value .

Сейчас я сериализую объекты в JSON, и я хотел бы, чтобы объект выше был сериализован так:

{
    "Price": 4.95
}

Но до сих пор я мог только сериализовать это, сделав поле публичной собственностью:

{
    "Price": {
        "Value": 4.95
    }
}

Вы знаете способ (предпочтительно с NewtonSoft.Json) сериализовать и десериализовать, как я описал?

Всего 1 ответ


Вы можете сделать это с помощью специального конвертера. Например:

public class PriceConverter : JsonConverter<Price>
{
    public override Price ReadJson(JsonReader reader, Type objectType, Price existingValue, 
        bool hasExistingValue, JsonSerializer serializer)
    {
        var value = Convert.ToDecimal(reader.Value);
        return new Price { Value = value };
    }

    public override void WriteJson(JsonWriter writer, Price value, JsonSerializer serializer)
    {
        writer.WriteValue(value.Value);
    }
}

Теперь вам просто нужно указать JSON.Net использовать конвертер. Один из способов - добавить его в настройки сериализатора:

//Create the settings object and add the converter
var settings = new JsonSerializerSettings();
settings.Converters.Add(new PriceConverter());

//Use the settings
var json = JsonConvert.SerializeObject(order, settings);
var newOrder = JsonConvert.DeserializeObject<Order>(json, settings);

В качестве альтернативы используйте атрибут, чтобы сообщить JSON.Net, какой конвертер использовать, либо в свойстве:

public class Order
{
    [JsonConverter(typeof(PriceConverter))]
    public Price Price { get; set; }
}

Или в классе:

[JsonConverter(typeof(PriceConverter))]
public class Price 
{
    public decimal Value { get; set; }  
}

Есть идеи?

10000