Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在试图通过序列化为JSON打印对象时会缺少一些成员?_C#_Json_Json.net - Fatal编程技术网

C# 为什么在试图通过序列化为JSON打印对象时会缺少一些成员?

C# 为什么在试图通过序列化为JSON打印对象时会缺少一些成员?,c#,json,json.net,C#,Json,Json.net,如何在C#中打印任意变量以打印所有成员 我用同样的技巧找到了三个答案: 这建议在其他答案中使用Json.NET序列化 , 但是,当我尝试使用以下代码时 using System; using System.Collections.Generic; using Newtonsoft.Json; public static class Program { public static void Main() { Test t1 = new Test(1, 2)

如何在C#中打印任意变量以打印所有成员

我用同样的技巧找到了三个答案:

  • 这建议在其他答案中使用Json.NET序列化
  • ,
但是,当我尝试使用以下代码时

using System;
using System.Collections.Generic;

using Newtonsoft.Json;

public static class Program
{
    public static void Main()
    {
        Test t1 = new Test(1, 2);
        {
            string json = JsonConvert.SerializeObject(t1, Formatting.Indented);
            Console.WriteLine(json);
        }
        Dump(t1);

        // Add 3 objects to a List.
        List<Test> list = new List<Test>();
        list.Add(new Test(1, 2));
        list.Add(new Test(3, 4));
        list.Add(new Test(5, 6));

        Console.WriteLine(list.ToString());
        {
            string json = JsonConvert.SerializeObject(list, Formatting.Indented);
            Console.WriteLine(json);
        }
    }

    public class Test
    {
        int A;
        int b;
        public Test(int _a, int _b)
        {
            A = _a;
            b = _b;
        }
    };

    public static void Dump<T>(this T x)
    {
        string json = JsonConvert.SerializeObject(x, Formatting.Indented);
        Console.WriteLine(json);
    }
}

为什么在使用JSON.NET序列化为JSON时,我的类成员都丢失了?

默认情况下,JSON.NET只会序列化public属性和字段。您的字段
A
b
私有的。要使Json.NET序列化非公共(私有或内部)成员,您可以:

  • 公开:

    public int A;
    public int b;
    
    但是,从风格上讲,如果要将其公开,最好将其转换为属性:

    public class Test
    {
        public int A { get; private set; }
        public int b { get; private set; }
        public Test(int a, int b)
        {
            this.A = a;
            this.b = b;
        }
    };
    
    只有getter需要是公共的,Json.NET才能序列化它们

  • 然后用
    [JsonProperty]
    标记:

    [JsonProperty]
    int A;
    [JsonProperty]
    int b;
    
    这也适用于非公共属性

  • 使用以下标记对象和字段:

    请注意,数据协定序列化是选择性加入的,因此您需要使用
    [DataMember]
    标记要序列化的每个成员。这有点讨厌,但如果你不想让你的c#模型依赖于Json.NET的话,这是很有用的

    这也适用于非公共属性

  • [JsonObject(MemberSerialization=MemberSerialization.Fields)]标记对象

    MemberSerialization
    中所述,
    MemberSerialization.Fields
    确保

    所有公共和私有字段都被序列化。可以使用JsonIgnoreAttribute或NonSerializedAttribute排除成员。还可以通过使用SerializableAttribute标记类并将DefaultContractResolver上的IgnoreSerializableAttribute设置为false来设置此成员序列化模式

    当然,这只会导致非公共字段被序列化,而不是非公共属性,但是如果您的目的是为了调试而打印任意变量,那么这可能就是您想要的

  • 用于序列化所有公共和非公共字段

    显示了几种序列化公共或私有属性和字段的方法

    另一个,DeclaredFieldContractResolver
    from,通过自动假定所有对象都标记为
    MemberSerialization.fields
    ,仅序列化公共或私有字段。您可以这样使用它:

    var settings = new JsonSerializerSettings
    {
        ContractResolver = DeclaredFieldContractResolver.Instance
    };
    var json = JsonConvert.SerializeObject(t1, Formatting.Indented, settings);
    
  • 创建序列化必要字段和属性的。由于字段是私有字段,因此需要为:

    然后像这样使用它:

    var json = JsonConvert.SerializeObject(t1, Formatting.Indented, new Test.TestJsonConverter());
    
    虽然这样做有效,但由于类型是嵌套的,因此您的模型仍然依赖于Json.NET,这使得选项2成为更好的选择


  • 如果您只是出于调试目的转储对象,那么#5可能是最好的选择。

    您需要将
    A
    b
    公开,或者将其标记为
    [JsonProperty]
    ,以便对其进行序列化。哦,谢谢。你要回答还是我删除这个?也许是和的副本?请回答并总结,@dbc。我认为这三种方法都是有价值的建议。我把它们公之于众了,现在它开始工作了!好的,可以。相关问题:.@xpt-增加选项#6。有点令人惊讶的是,我找不到一个现有的问题,这个问题的答案总结了所有可能的方法,用Json.NET序列化一个私有成员——只是零零碎碎的。是的,@dbc,零零碎碎的到处都是。非常感谢您将所有的拼图放在一个一站式的位置,并提供全面的解释,太棒了!
    [JsonObject(MemberSerialization = MemberSerialization.Fields)]
    public class Test
    {
        // Remainder as before...
    };
    
    var settings = new JsonSerializerSettings
    {
        ContractResolver = DeclaredFieldContractResolver.Instance
    };
    var json = JsonConvert.SerializeObject(t1, Formatting.Indented, settings);
    
    public class Test
    {
        public class TestJsonConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return typeof(Test).IsAssignableFrom(objectType);
            }
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var test = (Test)value;
    
                writer.WriteStartObject();
                writer.WritePropertyName(nameof(Test.A));
                serializer.Serialize(writer, test.A);
                writer.WritePropertyName(nameof(Test.b));
                serializer.Serialize(writer, test.b);
                writer.WriteEndObject();
            }
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
        // Remainder as before
    }
    
    var json = JsonConvert.SerializeObject(t1, Formatting.Indented, new Test.TestJsonConverter());