Is there a way to ignore get-only properties using the Json.NET serializer but without using JsonIgnore attributes?

For example, I have a class with these get properties:

    public Keys Hotkey { get; set; }

    public Keys KeyCode
    {
        get
        {
            return Hotkey & Keys.KeyCode;
        }
    }

    public Keys ModifiersKeys
    {
        get
        {
            return Hotkey & Keys.Modifiers;
        }
    }

    public bool Control
    {
        get
        {
            return (Hotkey & Keys.Control) == Keys.Control;
        }
    }

    public bool Shift
    {
        get
        {
            return (Hotkey & Keys.Shift) == Keys.Shift;
        }
    }

    public bool Alt
    {
        get
        {
            return (Hotkey & Keys.Alt) == Keys.Alt;
        }
    }

    public Modifiers ModifiersEnum
    {
        get
        {
            Modifiers modifiers = Modifiers.None;

            if (Alt) modifiers |= Modifiers.Alt;
            if (Control) modifiers |= Modifiers.Control;
            if (Shift) modifiers |= Modifiers.Shift;

            return modifiers;
        }
    }

    public bool IsOnlyModifiers
    {
        get
        {
            return KeyCode == Keys.ControlKey || KeyCode == Keys.ShiftKey || KeyCode == Keys.Menu;
        }
    }

    public bool IsValidKey
    {
        get
        {
            return KeyCode != Keys.None && !IsOnlyModifiers;
        }
    }

Do I need to add [JsonIgnore] to all of them (I also have many other classes), or there is better way to ignore all get-only properties?

推荐答案

You can do this by implementing a custom IContractResolver and using that during serialization. If you subclass the DefaultContractResolver, this becomes very easy to do:

class WritablePropertiesOnlyResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
        return props.Where(p => p.Writable).ToList();
    }
}

Here is a test program demonstrating how to use it:

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

class Program
{
    static void Main(string[] args)
    {
        Widget w = new Widget { Id = 2, Name = "Joe Schmoe" };

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            ContractResolver = new WritablePropertiesOnlyResolver()
        };

        string json = JsonConvert.SerializeObject(w, settings);

        Console.WriteLine(json);
    }
}

class Widget
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string LowerCaseName
    {
        get { return (Name != null ? Name.ToLower() : null); }
    }
}

Here is the output of the above. Notice that the read-only property LowerCaseName is not included in the output.

{"Id":2,"Name":"Joe Schmoe"}

Json相关问答推荐

Elasticsearch Go客户端错误:无效的SON格式:在中间件中索引文档时出错

在scala中将字符串列转换为 struct 的JSON映射

当有2个嵌套数组时展平复杂的JSON

如何在改装Android中将ResponseBody转换为JSONObject

需要有关在Ffltter应用程序中解码JSON的帮助;未处理的异常:类型不是类型转换中类型的子类型

如何将文件夹组织的.json文件合并为一个JSON文件,文件夹/文件名作为键

使用 jq 从带有转义反斜杠字符的嵌套 JSON 中提取数据

go 语言中的 JSON 到 XML

将boost::beast::multibuffer转换为std::istream

如何使用jolt将嵌套数据变成线性数据

jq json - 按键名 Select

嵌套 JSON 到 CSV(多级)

使用 KQL 和外部 data() 运算符从 json 文件中提取信息

使用基本身份验证通过 CURL 发布 JSON

如何从 HttpClient 解析 JSON 字符串?

如何获取json格式的KendoGrid显示数据?

如何在 swift 2 中获取 Alamofire.request().responseJSON 的结果值?

JSON 到 JSON 转换器

如何使用 Jackson 注释从 HttpResponse 反序列化 JSON 对象?

如何将 mysqli 结果转换为 JSON?