簡體   English   中英

自定義Newtonsoft.Json對象在單獨庫中的序列化

[英]Custom Newtonsoft.Json serialization of objects in a seperate library

我想為控制器編寫一個自定義json序列化程序,當它遇到非原始變量(不包括字符串/日期時間)時,它將在該對象中查找ID字段/屬性,然后而不是序列化整個對象,而是寫一個{ID,名稱}(其中ID是ID的值,而Name是數據對象的名稱)。

其背后的目的是我編寫一個Cache Viewer,但是緩存項可能會變得很大。 我可以只使用ID字段,而忽略UI中的其余部分,但是然后我可能在向響應中的大量數據發送方式方面遇到問題。

我在弄清楚我應該從哪里開始時遇到了麻煩,所以請問這個問題是否有點寬泛。

附加說明:我需要序列化的數據項位於單獨的庫中,並且我無權訪問它們,但可以保證它們都將使用ID字段。 如果我想念一些數據點是可以的,因為它們是非原始,非日期時間,非字符串字段。

到目前為止,這是我僅編寫原語的內容:

public class FieldsOnlyFormatterConfig : Attribute, IControllerConfiguration
    {
        public void Initialize(HttpControllerSettings settings,
            HttpControllerDescriptor descriptor)
        {
            // Clear the formatters list.
            settings.Formatters.Clear();
            var formatter = new JsonMediaTypeFormatter();
            formatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            formatter.SerializerSettings.ContractResolver = new CustomResolver();
            // Add a custom media-type formatter.
            settings.Formatters.Add(formatter);
        }


    }

    class CustomResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty prop = base.CreateProperty(member, memberSerialization);

            if (member.MemberType == MemberTypes.Field && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)))
            {
                prop.ShouldSerialize = obj => true;
            }
            else
            {
                prop.ShouldSerialize = obj => false;
            }

            return prop;
        }
    }

因此,經過一些擺弄,我能夠弄清楚如何實現自己想要的目標。

我更改了自定義解析器以檢測我的屬性類型是否為DataItem,然后將prop.Converter設置為使用自定義jsonConverter:

class CustomResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty prop = base.CreateProperty(member, memberSerialization);

            if (member.MemberType == MemberTypes.Field && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)))
            {
                prop.ShouldSerialize = obj => true;
            }
            else if (prop.PropertyType.IsSubclassOf(typeof(DataItem)))
            {
                prop.ShouldSerialize = obj => true;
                prop.Converter = new DataItemConverter();
            }
            else
            {
                prop.ShouldSerialize = obj => false;
            }

            return prop;
        }
    }

在自定義json轉換器中,在WriteJson上,我將該對象轉換為DataItem(一個類,我知道我想要繼承的所有內容,該類具有我正在尋找的“ id”字段),然后進行了一些自定義寫入:

class DataItemConverter: JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var di = value as DataItem;
            writer.WriteStartObject();
            writer.WritePropertyName("id");
            writer.WriteValue(di.Id);
            writer.WriteEndObject();
        }
    }

暫無
暫無

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

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