web-dev-qa-db-ja.com

JSONシリアル化オブジェクトから空の文字列プロパティを削除する

クラスがあります。これにはいくつかのプロパティがあります。10としましょう。これらの10のうち、3はデータで埋められ、残りの7は空白です。空の文字列 ""これを参照として使用 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」はUserインスタンスです。運が悪いのですが、「t」には10個のプロパティすべてが返されます

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

ご覧のとおり、userIDとpasswordだけが入力されています。しかし、ssn、empIDなどがまだ表示されています。ユーザーIDとパスワードのみが必要です。任意の助けいただければ幸いです。

11
RookieAppler

プロパティ[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; }
}
18
Brenton Major

受け入れられた回答は機能しますが、ゼロ値の整数プロパティも削除されます。大きなオブジェクトを処理するためのより一般的なものを探していました。

ここで素晴らしい答えが見つかりました: 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
    });
1
Nick Evans

次のように2つのアノテーションを使用することもできます。

[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Category { get; set; }
0
Burak Doğan