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

mku*_*kul 2 c# json json.net

我的目标是序列化没有任何属性的属性和具有特定自定义属性的属性。

对于以下课程:

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

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

    [CustomAttributeB]
    public string Status { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我调用一个方法时Serialize(object, CustomAttributeA),我想要以下输出:

{
    "Id" : someId,
    "Text" : "some text"
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时Serialize(object, CustomAttributeB),我想拥有以下内容:

{
    "Id" : someId,
    "Status" : "some status"
}
Run Code Online (Sandbox Code Playgroud)

我读过可以通过创建一个自定义来实现这一点ContractResolver,但是在这种情况下,我必须创建两个单独的合同解析器吗?

Bri*_*ers 5

您不需要两个单独的解析器即可实现您的目标。只需将自定义ContractResolver泛型设置为通用类型即可,其中的type参数表示序列化时要查找的属性。

例如:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建一个辅助方法来创建解析器并序列化您的对象:

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);
}
Run Code Online (Sandbox Code Playgroud)

当您要序列化时,请像这样调用助手:

string json = Serialize<CustomAttributeA>(msg);
Run Code Online (Sandbox Code Playgroud)

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