Remove empty string properties from json serialized object

前端 未结 4 1107
暖寄归人
暖寄归人 2020-12-15 23:06

I have a class. It has several properties lets say 10. Out of these 10, 3 are filled with data remaining 7 are blank.i.e. empty strings \"\" Used this link as reference. I w

相关标签:
4条回答
  • 2020-12-15 23:22

    Just decorating the properties [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] ONLY should do what you want. Unless the property is getting set to an empty string.

    Just wondering, why do you need the DataMemeber attribute?

    Here is a link to a working dotnetfiddle

    using System;
    using Newtonsoft.Json;
    using System.ComponentModel;
    
    public class Program
    {
    
        public static void Main()
        {
            var user = new User();
    
            user.UserID = "1234";
            user.ssn = "";
    
            var settings = new JsonSerializerSettings();
    
            settings.NullValueHandling = NullValueHandling.Ignore;
            settings.DefaultValueHandling = DefaultValueHandling.Ignore;
    
    
            Console.WriteLine(JsonConvert.SerializeObject(user, settings));
        }
    }
    
    public class User
    {
        [DefaultValue("")]
        public string UserID { get; set; }
    
        [DefaultValue("")]
        public string ssn { get; set; }
    
        [DefaultValue("")]
        public string empID { get; set; }
    
        [DefaultValue("")]
        public string schemaAgencyName { get; set; }
    
        [DefaultValue("")]
        public string givenName { get; set; }
    
        [DefaultValue("")]
        public string familyName { get; set; }
    
        [DefaultValue("")]
        public string password { get; set; }
    }
    
    0 讨论(0)
  • 2020-12-15 23:29

    i have done this with a converter.

    using System;
    
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace TestApp.JsonConverterResolver
    {
        public class IgnoreEmptyStringsConverter : JsonConverter
        {
        #region Methods
    
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(string);
            }
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                            JsonSerializer serializer)
            {
                var theValue = reader.Value?.ToString();
    
                return !string.IsNullOrWhiteSpace(theValue) ? theValue : null;
            }
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                if (!string.IsNullOrWhiteSpace(value.ToString()))
                {
                    JToken token = JToken.FromObject(value.ToString(), serializer);
                    token.WriteTo(writer);
                    return;
                }
    
                writer.WriteNull();
            }
    
        #endregion
        }
    }
    

    Example person model class:

    public class Person
    {
        public string Name { get; set; }
    }
    

    And the ueage:

    var serializerSettings = new JsonSerializerSettings
         {
             Formatting           = Newtonsoft.Json.Formatting.Indented,
             NullValueHandling    = Newtonsoft.Json.NullValueHandling.Ignore,
             Converters           = new List<JsonConverter> {new IgnoreEmptyStringsConverter()}
         };
    
    var person = JsonConvert.DeserializeObject<Person>("{ \"Name\":\"\" }", serializerSettings);
    
    var jsonPerson = JsonConvert.SerializeObject(new Person { Name = "" }, serializerSettings);
    

    I just wrote that out of my head. But I think that's how I solved it at some point. Maybe it helps someone.

    0 讨论(0)
  • 2020-12-15 23:32

    Although the accepted answers works, it also removes integer properties of zero value. I was looking for something more generic to work with large objects.

    Found a great answer here: https://codearticles.ru/articles/2905?AspxAutoDetectCookieSupport=1

    And consolidated it for our use case as below:

    public class ShouldSerializeContractResolver : DefaultContractResolver
    {
        public static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
    
            if (property.PropertyType == typeof(string))
            {
                // Do not include emptry strings
                property.ShouldSerialize = instance =>
                {
                    return !string.IsNullOrWhiteSpace(instance.GetType().GetProperty(member.Name).GetValue(instance, null) as string);
                };
            }
            else if (property.PropertyType == typeof(DateTime))
            {
                // Do not include zero DateTime
                property.ShouldSerialize = instance =>
                {
                    return Convert.ToDateTime(instance.GetType().GetProperty(member.Name).GetValue(instance, null)) != default(DateTime);
                };
            }
            else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
            {
                // Do not include zero-length lists
                switch (member.MemberType)
                {
                    case MemberTypes.Property:
                        property.ShouldSerialize = instance =>
                        {
                            var enumerable = instance.GetType().GetProperty(member.Name).GetValue(instance, null) as IEnumerable;
                            return enumerable != null ? enumerable.GetEnumerator().MoveNext() : false;
                        };
                        break;
                    case MemberTypes.Field:
                        property.ShouldSerialize = instance =>
                        {
                            var enumerable = instance.GetType().GetField(member.Name).GetValue(instance) as IEnumerable;
                            return enumerable != null ? enumerable.GetEnumerator().MoveNext() : false;
                        };
                        break;
                }
            }
            return property;
        }
    }
    

    This can be used as follows:

    JsonConvert.SerializeObject(o,
        Newtonsoft.Json.Formatting.None,
        new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = ShouldSerializeContractResolver.Instance
        });
    
    0 讨论(0)
  • 2020-12-15 23:34

    You can also use two annotations as follows:

    [DefaultValue("")]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public string Category { get; set; }
    
    0 讨论(0)
提交回复
热议问题