简体   繁体   English

Json.NET JsonConvert.DeserializeObject() 返回值 null

[英]Json.NET JsonConvert.DeserializeObject() return null value

i tried to Deserialize this string:我试图反序列化这个字符串:

string _jsonObject = {\"Ad\":{\"Type\":\"Request"\,
         \"IdAd\":\"xxx@xxx.com\",
         \"Category\":\"cat\",
         \"SubCategory\":\"subcat\"},
\"Position\":{\"Latitude\":\"38.255\",
              \"Longitude\":\"1.2\",
              \"Imei\":\"0123456789\"};
}";

Message _message = JsonConvert.DeserializeObject<Message>(_jsonObject);

Works pretty for "Ad" but not instanciate "Position".适用于“广告”但不能实例化“位置”。 Any idea?任何的想法?

I forgot to make the properties public.我忘了公开这些属性。 Don't forget to do that...不要忘记这样做...

In the interest of helping others that may be experiencing this issue, or one related to it...为了帮助可能遇到此问题或与之相关的其他人...

In my case, I had an object with an array of other objects, and one of the reference-type properties on those sub-objects was always null after deserialization.就我而言,我有一个包含其他对象数组的对象,并且这些子对象上的一个引用类型属性在反序列化后始终为空。 I tried all kinds of things, including downloading the JSON.Net source and stepping through it to find the failure point.我尝试了各种方法,包括下载 JSON.Net 源代码并逐步查找故障点。

To make a long story short, the problem was, of course, my own.长话短说,问题当然是我自己的。 Here is a highly simplified version of my JSON and classes.这是我的 JSON 和类的高度简化版本。

JSON JSON

{
    "$id": "1",
    "RowCount": 10,
    "Rows": [{
        "$id": 2",
        "ItemId": "1",
        "ItemName": "Some Item",
        "Owner": {
            "Name": "John Doe",
            "Id": "711D04F5-586F-4FD4-8369-4C00B51DD86F",
            // other properties...
        },
        "OwnerId": "711D04F5-586F-4FD4-8369-4C00B51DD86F"
    },
    // more rows
    ]
}

Classes班级

public class Items
{
    public int RowCount { get; set; }
    public IEnumerable<Item> Rows { get; set; }
}

public class Item
{
    private string ownerId;

    public string ItemId { get; set; }
    public string ItemName { get; set; }
    public Person Owner { get; set; }
    public string OwnerId
    {
        get { return this.ownerId; }
        set {
            if (value != this.ownerId)
            {
                this.Owner = null;
            }
            this.ownerId = value;
        }
    }
}

public class Person
{
    public string Name { get; set; }
    public string Id { get; set; }
    // other properties
}

What was happening is that, because the Owner property appeared in the JSON prior to the OwnerId property, when the OwnerId property was set, the setter code determined that the current value was not the same as the value being set (since the current value was null), so it set the Owner property to null.发生的事情是,因为Owner属性出现在OwnerId属性之前的 JSON 中,当设置OwnerId属性时,setter 代码确定当前值与正在设置的值不同(因为当前值是null),因此它将Owner属性设置为 null。

To fix it I also check the value being set against the id of the Owner object as well, and skip setting Owner to null if they are the same.为了修复它,我还检查了针对Owner对象的 id 设置的值,如果它们相同,则跳过将Owner设置为 null。

Admittedly, the cause of my problem may not be the same for everyone, but this is at least a cautionary tale to double-check what is happening when your objects are being initialized during deserialization.诚然,我的问题的原因可能对每个人都不同,但这至少是一个警示故事,用于仔细检查在反序列化期间初始化对象时发生的情况。

I don't know how you are trying to deserialize, but this should work....我不知道你是如何尝试反序列化的,但这应该有效......

string json = "{\"Ad\":{\"Type\":\"Request\",         \"IdAd\":\"xxx@xxx.com\",         \"Category\":\"cat\",         \"SubCategory\":\"subcat\"},\"Position\":{\"Latitude\":\"38.255\",              \"Longitude\":\"1.2\",              \"Imei\":\"0123456789\"}}";
var obj = JsonConvert.DeserializeObject<RootObject>(json);

public class Ad
{
    public string Type { get; set; }
    public string IdAd { get; set; }
    public string Category { get; set; }
    public string SubCategory { get; set; }
}

public class Position
{
    public string Latitude { get; set; }
    public string Longitude { get; set; }
    public string Imei { get; set; }
}

public class RootObject
{
    public Ad Ad { get; set; }
    public Position Position { get; set; }
}

Make sure the name of array in JSON matches with property name in your class确保 JSON 中的数组名称与类中的属性名称匹配

Illustrating (Look for "Components"):说明(寻找“组件”):

JSON: JSON:

{  
  "Components": [
    {
      "Attribute1": "ABC",
      "Attribute2": "XYZ"      
    }
  ]
}

Class:班级:

public class MyClass
{
    public IList<Component> Components { get; set; }
}

Deserialize:反序列化:

JsonConvert.DeserializeObject<MyClass>(File.ReadAllText(@"ComponentSet.json"))

In my case there is a more subtle error.就我而言,有一个更微妙的错误。 It is easy to add leading or trailing spaces in the json keys by mistake.很容易错误地在 json 键中添加前导或尾随空格。 When that happens, the key is not recognized and attempting to deserialize it sets the value to null.发生这种情况时,无法识别键并尝试反序列化它会将值设置为 null。

For example: {" id": 123}例如: {" id": 123}
This id field is not recognized because of the leading space " id" .由于前导空格" id"无法识别此id字段。 To fix it, fix the json to have instead "id" .要修复它,请修复 json 以改为使用"id"

My problem was that I was including the class name at the beginning of my JSON string.我的问题是我在 JSON 字符串的开头包含了类名。 I had copy-pasted from the serialized output of another class that contained the one I wanted to deserialize and I had purposefully included the class name thinking this was the correct JSON string.我从另一个类的序列化输出中复制粘贴,其中包含我想要反序列化的类,并且我故意包含类名,认为这是正确的 JSON 字符串。 Once I removed the class name from my JSON string, it deserialized just fine.一旦我从我的 JSON 字符串中删除了类名,它就可以很好地反序列化。

This article was helpful in realizing this: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/4d766a28-ff38-477f-8abf-48ed01f74cd2/jsonconvertdeserializeobjectlttgtjsonstring-returning-all-propertieslttgt-as-null?forum=wpdevelop这篇文章有助于实现这一点: https : //social.msdn.microsoft.com/Forums/windowsapps/en-US/4d766a28-ff38-477f-8abf-48ed01f74cd2/jsonconvertdeserializeobjectlttgtjsonstring-returning-all-propertieslttgt-as-null?论坛= wpdevelop

I did not see this answer here so I am including it hoping that it helps those who made the same silly mistake as me.我在这里没有看到这个答案,所以我把它包括在内,希望它能帮助那些和我犯同样愚蠢错误的人。

就我而言,我的类属性有内部设置器,将它们设置为公开后,问题就解决了。

I've never had any issues using Newtonsoft.Json, but decided to go with built in json libraries in latest project.我在使用 Newtonsoft.Json 时从未遇到过任何问题,但决定在最新项目中使用内置的 json 库。 Ended up with null result.以空结果结束。 Turns out the following will fail:事实证明以下将失败:

JSON: JSON:

{
   "myProperty": "abc"
}

CLASS:班级:

public void MyClass
{
   public string MyProperty { get; set; }
}

Why does it fail?为什么会失败? "myProperty" in json is camel case (starts with lower case letter), while MyProperty in MyClass starts with upper case letter. json 中的“myProperty”是驼峰式(以小写字母开头),而 MyClass 中的 MyProperty 以大写字母开头。 If you make both cases the same it works.如果您使两种情况相同,则它起作用。 I tried figuring out how to configure case insensitivity for the entire app, but apparently that's not possible to do, so I went back to Newtonsoft.JSON and the problem went away.我试图弄清楚如何为整个应用程序配置不区分大小写,但显然这是不可能的,所以我回到 Newtonsoft.JSON 并且问题消失了。

In my case, it was because I did not have a public constructor on my class.就我而言,这是因为我的班级没有公共构造函数。

This is what my class originally looked like:这是我的班级最初的样子:

public class TreeGroup
{
    public string Name { get; set; }
    public SiteGroup Group { get; set; }
    public List<TreeMimicObject> Children { get; set; }
   
    public TreeGroup(SiteGroup item)
    {
        // Notice this constructor takes a SiteGroup object and there 
        // is no default constructor
    }
}

so I changed the class from the above to this:所以我把班级从上面改成了这样:

public class TreeGroup
{
    public string Name { get; set; }
    public SiteGroup Group { get; set; }
    public List<TreeMimicObject> Children { get; set; }

    public TreeGroup()
    {
        // Added this default constructor here!!
    }

    public TreeGroup(SiteGroup item)
    {
        // ...
    }
}

and it worked!它奏效了!

In my case the problem was deserializeobject return null when try to convert null value from json to int .在我的例子中,问题是当尝试将null值从 json 转换为int时, deserializeobject化对象返回null

    public class ItemCalcResModel
    {
        public int cartId;
    }

I solved the problem by enable nullable in project :我通过在项目中启用nullable解决了这个问题:

    #nullable enable
    public class ItemCalcResModel
    {
        public int? cartId;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JSON.net与JsonConvert.DeserializeObject的问题 - JSON.net problem with JsonConvert.DeserializeObject Json.NET JsonConvert.DeserializeObject() - Json.NET JsonConvert.DeserializeObject() JsonConvert.DeserializeObject 返回空值 - JsonConvert.DeserializeObject return null value 使用 JSON.net(JsonConvert.SerializeObject 或 JsonConvert.DeSerializeObject)为缺少的复杂属性设置默认值 - Set Default value for missing Complex properties with JSON.net (JsonConvert.SerializeObject or JsonConvert.DeSerializeObject) JsonConvert.DeserializeObject &lt;&gt;使用Json.Net在Mac上的xamarin Studio中返回null - JsonConvert.DeserializeObject<> returns null in xamarin studio on mac using Json.Net JSON.Net,JsonConvert.DeserializeObject - 反序列化的问题 - JSON.Net, JsonConvert.DeserializeObject - problems with deserialization 使用JsonConvert.DeserializeObject(Json.net)反序列化-按动态类型 - Deserialize using JsonConvert.DeserializeObject (Json.net) - by dynamic type JsonConvert.DeserializeObject返回null - JsonConvert.DeserializeObject return null JsonConvert.DeserializeObject 返回 null asp.net core - JsonConvert.DeserializeObject return null asp.net core JSon.Net JObject.FromObject Vs JsonConvert.DeserializeObject <JObject>(JsonConvert.SerializeObject(obj)); - JSon.Net JObject.FromObject Vs JsonConvert.DeserializeObject<JObject>(JsonConvert.SerializeObject(obj));
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM