【问题标题】:How to serialize an object to a JSON string property instead of an object using Json.Net如何使用 Json.Net 将对象序列化为 JSON 字符串属性而不是对象
【发布时间】:2014-10-13 17:23:03
【问题描述】:

我有以下类结构。我想要实现的不是Bar 序列化为JSON 中的对象,而是序列化为其内部属性Name 值的字符串并忽略Id 属性。而且我没有需要反序列化它的场景,但是我必须从具有其他属性的数据库中加载 Bar 对象并进行一些内部操作,但不将其用于传输。

class Foo
{
    [JsonProperty("bar")]
    public Bar Bar { get; set; }
}

class Bar
{
    [JsonIgnore]
    public Guid Id { get; set; }
    [JsonProperty]
    public string Name { get; set; }
}

预期的 JSON:

{
    bar: "test"
}

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    使用自定义JsonConverter,您可以控制转换以输出您想要的任何内容。

    类似:

        public class BarConverter : JsonConverter
        {
    
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(Bar);
            }
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var bar = value as Bar;
                serializer.Serialize(writer, bar.Name);
            }
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                  // Note: if you need to read to, you'll need to implement that here too
                  // otherwise just throw a NotImplementException and override `CanRead` to return false
                  throw new NotImplementedException();
            }
        }
    

    然后,您可以使用JsonConverterAttribute 装饰您的属性或Bar 类(取决于您是否总是希望Bar 像这样序列化,或者仅用于此属性):

    [JsonConverter(typeof(BarConverter))]
    public Bar Bar { get; set; }
    

    或者:

    [JsonConverter(typeof(BarConverter))]
    public class Bar
    

    另一种“快速而肮脏”的方法是只拥有一个将被序列化的 shadow 属性:

    public class Foo
    {
        [JsonProperty("bar")]         // this will be serialized as "bar"
        public string BarName 
        {
            get { return Bar.Name; }
        }
    
        [JsonIgnore]                  // this won't be serialized
        public Bar Bar { get; set; }
    }
    

    请注意,如果您希望能够阅读,那么您还需要提供一个 setter 并弄清楚如何将字符串名称转换回 Bar 的实例。这就是快速而肮脏的解决方案有点令人不快的地方,因为您没有简单的方法将设置 BarName 限制为仅在反序列化期间。

    【讨论】:

    • JsonConverter 方式开箱即用,无需引入任何其他属性!谢谢
    猜你喜欢
    • 2013-07-09
    • 1970-01-01
    • 2014-08-22
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    相关资源
    最近更新 更多