从 json 序列化对象中删除空字符串属性

问题描述 投票:0回答:5

我有课。它有几个属性,比方说 10 个。在这 10 个属性中,3 个填充了数据,其余 7 个为空白。即空字符串“”使用此link作为参考。我只想显示非空和非空字符串属性。但最终输出具有全部 10 个属性。我只想看3个。

namespace Mynamespace.ValueObjects
{
[DataContract]
public class User
{
      [DataMember(Name ="userID", IsRequired = false,EmitDefaultValue = false)]
    public string userID { get; set; }
      [DataMember(Name ="ssn", IsRequired = false,EmitDefaultValue = false)]
    public string ssn { get; set; }
      [DataMember(Name ="empID", IsRequired = false,EmitDefaultValue = false)]
    public string empID { get; set; }
      [DataMember(Name ="schemaAgencyName", IsRequired = false,EmitDefaultValue = false)]
    public string schemaAgencyName { get; set; }
      [DataMember(Name ="givenName", IsRequired = false,EmitDefaultValue = false)]
    public string givenName { get; set; }
      [DataMember(Name ="familyName", IsRequired = false,EmitDefaultValue = false)]
    public string familyName { get; set; }
      [DataMember(Name ="password", IsRequired = false,EmitDefaultValue = false)]
    public string password { get; set; }
      ....

}

}

我也尝试过

 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]

也是属性。没有运气。我也喜欢这个

 var t = JsonConvert.SerializeObject(usr, Newtonsoft.Json.Formatting.None,
                                                new JsonSerializerSettings
                                                    {NullValueHandling = NullValueHandling.Ignore});

其中“usr”是用户实例。我的意思是,“t”带着所有 10 个属性一起回来了

{"userID":"vick187","ssn":"","empID":"","schemaAgencyName":"","givenName":"","familyName":"","password":"pwd1234",...}

如您所见,仅填充了用户 ID 和密码。但我的 ssn、empID 等仍然出现。我只想要用户名和密码。任何帮助将不胜感激。

c# .net json serialization
5个回答
38
投票

只是装饰属性

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
只应该做你想做的事。 除非该属性被设置为空字符串。

只是想知道,为什么需要 DataMemeber 属性?

这里是一个工作 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; }
}

16
投票

您还可以使用两个注释,如下所示:

[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Category { get; set; }

10
投票

虽然接受的答案有效,但它也删除了零值的整数属性。我一直在寻找更通用的东西来处理大型物体。

在这里找到了一个很好的答案:https://codearticles.ru/articles/2905?AspxAutoDetectCookieSupport=1

并将其整合到我们的用例中,如下所示:

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;
    }
}

可以按如下方式使用:

JsonConvert.SerializeObject(o,
    Newtonsoft.Json.Formatting.None,
    new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore,
        ContractResolver = ShouldSerializeContractResolver.Instance
    });

3
投票

我已经用转换器完成了此操作。

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
    }
}

人物模型类示例:

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

还有用法:

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);

我只是凭空写下这句话。 但我认为这就是我在某个时候解决这个问题的方法。 也许它对某人有帮助。


0
投票

太简单了

只需将 ShouldSerializePPPPPP() 放入类中 然后您可以定义自己的规则

public string Contact { get; set; } = string.Empty;
public bool ShouldSerializeContact() => !string.IsNullOrWhiteSpace(Contact);
© www.soinside.com 2019 - 2024. All rights reserved.