简体   繁体   English

Json.Net中的自定义属性处理

[英]Custom attribute handling in Json.Net

My goal is to serialize properties that don't have any attributes and properties which have a specific custom attribute. 我的目标是序列化没有任何属性的属性和具有特定自定义属性的属性。

For the following class: 对于以下课程:

public class Msg
{
    public long Id { get; set; }

    [CustomAttributeA]
    public string Text { get; set; }

    [CustomAttributeB]
    public string Status { get; set; }
}

When I call a method Serialize(object, CustomAttributeA) , I want to have the following output: 当我调用方法Serialize(object, CustomAttributeA) ,我想要以下输出:

{
    "Id" : someId,
    "Text" : "some text"
}

And when I call Serialize(object, CustomAttributeB) , I want to have following: 当我调用Serialize(object, CustomAttributeB) ,我想要以下内容:

{
    "Id" : someId,
    "Status" : "some status"
}

I have read that it's possible to achieve this by creating a custom ContractResolver , but in this case must I create two separate contract resolvers? 我已经读到可以通过创建自定义ContractResolver来实现这一点,但是在这种情况下,我必须创建两个单独的合同解析器吗?

You do not need two separate resolvers to achieve your goal. 您不需要两个单独的解析器即可实现您的目标。 Just make the custom ContractResolver generic, where the type parameter represents the attribute you are looking for when serializing. 只需将自定义ContractResolver通用,其中type参数表示序列化时要查找的属性。

For example: 例如:

public class CustomResolver<T> : DefaultContractResolver where T : Attribute
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

        foreach (JsonProperty prop in list)
        {
            PropertyInfo pi = type.GetProperty(prop.UnderlyingName);
            if (pi != null)
            {
                // if the property has any attribute other than 
                // the specific one we are seeking, don't serialize it
                if (pi.GetCustomAttributes().Any() &&
                    pi.GetCustomAttribute<T>() == null)
                {
                    prop.ShouldSerialize = obj => false;
                }
            }
        }

        return list;
    }
}

Then, you can make a helper method to create the resolver and serialize your object: 然后,您可以创建一个辅助方法来创建解析器并序列化您的对象:

public static string Serialize<T>(object obj) where T : Attribute
{
    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        ContractResolver = new CustomResolver<T>(),
        Formatting = Formatting.Indented
    };
    return JsonConvert.SerializeObject(obj, settings);
}

When you want to serialize, call the helper like this: 当您要序列化时,请像这样调用助手:

string json = Serialize<CustomAttributeA>(msg);

Demo fiddle: https://dotnetfiddle.net/bRHbLy 演示小提琴: https : //dotnetfiddle.net/bRHbLy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM