从 json 序列化对象中删除空字符串属性
Remove empty string properties from json serialized object
我有一个class。它有几个属性,比如 10 个。在这 10 个中,3 个填充了数据,其余 7 个是 blank.i.e。空字符串 "" 使用此 link 作为参考。我只想显示 NON-NULL 和 NON-EMPTY 字符串属性。但最终输出具有所有 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 等。我只想要用户名和密码。任何帮助将不胜感激。
只是装饰属性 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
ONLY 应该做你想做的。除非 属性 被设置为空字符串。
只是想知道,为什么需要 DataMemeber 属性?
这是一个 link 到工作 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; }
}
虽然接受的答案有效,但它也删除了零值的整数属性。我一直在寻找更通用的东西来处理大对象。
在这里找到了一个很好的答案: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
});
也可以使用如下两种注解:
[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Category { get; set; }
我已经用转换器做到了。
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
}
}
示例人物模型class:
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);
我只是在脑海中写下了这些。
但我认为这就是我在某个时候解决它的方式。
也许对某人有帮助。
我有一个class。它有几个属性,比如 10 个。在这 10 个中,3 个填充了数据,其余 7 个是 blank.i.e。空字符串 "" 使用此 link 作为参考。我只想显示 NON-NULL 和 NON-EMPTY 字符串属性。但最终输出具有所有 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 等。我只想要用户名和密码。任何帮助将不胜感激。
只是装饰属性 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
ONLY 应该做你想做的。除非 属性 被设置为空字符串。
只是想知道,为什么需要 DataMemeber 属性?
这是一个 link 到工作 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; }
}
虽然接受的答案有效,但它也删除了零值的整数属性。我一直在寻找更通用的东西来处理大对象。
在这里找到了一个很好的答案: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
});
也可以使用如下两种注解:
[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Category { get; set; }
我已经用转换器做到了。
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
}
}
示例人物模型class:
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);
我只是在脑海中写下了这些。 但我认为这就是我在某个时候解决它的方式。 也许对某人有帮助。