簡體   English   中英

自定義 JSON 合約解析器忽略所有沒有自定義注釋的屬性

[英]Custom JSON contract resolver to ignore all properties without a custom annotation

我希望將[JsonProperty("name")]![JsonIgnore]組合到我自己的自定義解析器中,我只需要一些語法幫助。

因此,在序列化此 class 時,我想忽略所有沒有我的自定義屬性的屬性,並指定屬性的序列化名稱,如下所示:

public class MyClass
{
    [MyCustomProperty("name")]
    public string SomeName { get; set; }

    [MyCustomProperty("value")]
    public string SomeValue { get; set; }
    
    public string AnotherName {get; set; }
    
    public string AnotherValue {get; set; }
}

預期結果:

{
    "name": "Apple",
    "value": "Delicious"
}

這是我使用解析器所取得的進展:

public class MyCustomProperty : Attribute
{
    public string Property { get; set; }
    public MyCustomProperty(string property)
    {
        Property = property;
    }
}

public class CustomResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        Type itemType = property.PropertyType.GetGenericArguments().First();
        MyCustomProperty customProperty = itemType.GetCustomAttribute<MyCustomProperty>();
        property.PropertyName = MyCustomProperty.Property;
        return property;
    }
}

如果沒有屬性部分,我不確定在哪里添加忽略

JsonProperty上有一個AttributeProvider ,您可以使用它來查找該屬性的自定義屬性。 我建議你使用它。 所以基本上你會嘗試獲取屬性,如果它存在,你就像你正在做的那樣設置名稱,否則你設置Ignored = true

順便說一句,我建議您將MyCustomProperty class 重命名為MyCustomPropertyAttribute ,以符合從System.Attribute派生的類的標准約定 (不用擔心, [MyCustomProperty("name")]注釋不需要更改,因為Attribute部分在注釋中是可選的。)您還應該將[AttributeUsage]屬性應用於您的自定義屬性 class 以指示它是如何被允許的要使用的。 最后,我建議您將Property重命名為PropertyName以明確它是一個名稱(字符串)而不是屬性本身(例如PropertyInfo )。

所以代碼看起來像這樣:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class MyCustomPropertyAttribute : Attribute
{
    public string PropertyName { get; set; }
    public MyCustomPropertyAttribute(string propertyName)
    {
        PropertyName = propertyName;
    }
}

public class CustomResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        MyCustomPropertyAttribute customAttribute = (MyCustomPropertyAttribute)property.AttributeProvider.GetAttributes(typeof(MyCustomPropertyAttribute), true).FirstOrDefault();
        if (customAttribute != null)
        {
            property.PropertyName = customAttribute.PropertyName;
        }
        else
        {
            property.Ignored = true;
        }
        return property;
    }
}

工作演示: https://dotnetfiddle.net/thQc0f


綜上所述,您實際上並不需要自定義解析器來獲得您想要的行為。 您可以簡單地將[JsonObject(MemberSerialization.OptIn)]屬性應用於MyClass ,然后在您想要包含的那些屬性上使用正常的[JsonProperty]屬性。 任何未標記的屬性都將被忽略。 (請參閱 Json.Net 文檔中的序列化屬性。)

[JsonObject(MemberSerialization.OptIn)]
public class MyClass
{
    [JsonProperty("name")]
    public string SomeName { get; set; }

    [MyCustomProperty("value")]
    public string SomeValue { get; set; }
    
    public string AnotherName {get; set; }
    
    public string AnotherValue {get; set; }
}

演示: https://dotnetfiddle.net/qY6nGR

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM