简体   繁体   English

反序列化将值转换为特定类型的JSON错误

[英]Deserialize JSON error converting value to specific type

I have a Django backend model with REST Services which create JSON. 我有一个带有REST服务的Django后端模型,该模型创建JSON。 The JSON I get (part of it) looks like follows: 我得到的JSON(部分)如下所示:

[
  {
    "id": 1,
    "username": "T1",
    "tel": "",
    "created_on": "2018-09-03T16:29:20.903315Z",
    "last_login": null,
    "hasContacts": [

    ],
    "myChanges": [

    ],
    "helpsOnChanges": [

    ],
    "shouldHelpOnChanges": [
      1
    ],
    "welldone_set": [
      {
        "id": 1,
        "created_on": "2018-09-03T16:29:20.925327Z",
        "comment": "You rock1",
        "change": 1,
        "helper": 1
      }
    ]
  },
  {
    "id": 2,
    "username": "T2",
    "tel": "",
    "created_on": "2018-09-03T16:29:20.903315Z",
    "last_login": null,
    "hasContacts": [

    ],
    "myChanges": [
      {
        "id": 1,
        "name": "Stop smoking",
        "created_on": "2018-09-03T16:29:20.923315Z",
        "change": "I want to stop smoking",
        "finished_on": null,
        "success": false,
        "helpee": 2,
        "helper": [

        ],
        "requestedHelpers": [
          1
        ],
        "welldone_set": [
          {
            "id": 1,
            "created_on": "2018-09-03T16:29:20.925327Z",
            "comment": "You rock1",
            "change": 1,
            "helper": 1
          }
        ]
      }
    ],
    "helpsOnChanges": [

    ],
    "shouldHelpOnChanges": [

    ],
    "welldone_set": [

    ]
  }
]

The explicit error of the JSONConvert.Deserialize call now is: JSONConvert.Deserialize调用的显式错误现在是:

2018-09-02T18:57:13.145 Error Error deserializing App.ViewModels.Change. 2018-09-02T18:57:13.145错误反序列化App.ViewModels.Change时出错。 Error converting value 1 to type 'App.ViewModels.User'. 将值1转换为类型'App.ViewModels.User'时出错。 Path '[0].myChanges[0].helpee', line 1, position 275. 路径'[0] .myChanges [0] .helpee',第1行,位置275。

This refers to the "helpee" attribute, which is of type user. 这指的是“ helpee”属性,其类型为user。 The Django framework only puts the id of the user in this list, which makes sense as the user was already transmitted in this JSON prior to the result above. Django框架仅将用户的ID放在此列表中,这是有道理的,因为在上述结果之前,该JSON中已经传输了用户。

So why cant Newtonsoft.JSON not resolve this? 那么,为什么Newtonsoft.JSON无法解决此问题? Cant it associate this id with the actual User instance of the same id? 能否将此ID与具有相同ID的实际User实例相关联?

Thank you in advance! 先感谢您! Wolf

Edit : For clarification the serializer of my Django Backend: 编辑:为澄清我的Django后端的序列化器:

    class ChangeSerializer(serializers.ModelSerializer):
        welldone_set = WellDoneSerializer(many=True)
        class Meta:
            model = Change
            fields = ('id',
                      'name', 
                      'created_on', 
                      'change', 
                      'finished_on', 
                      'success', 
                      'helpee', 
                      'helper', 
                      'requestedHelpers', 
                      'welldone_set') 
ChangeSerializer.helpee = UserSerializer();
ChangeSerializer.helper = UserSerializer(many=True);
ChangeSerializer.requestedHelpers = UserSerializer(many=True);

As you can see, helpee is actually an object and not just an id 如您所见,helpee实际上是一个对象,而不仅仅是一个id

Edit 2: Updated the json to be complete 编辑2:将json更新为完整

Edit 3: My deserializer method. 编辑3:我的反序列化方法。 The exception gets thrown in the deserializer line. 在反序列化器行中引发异常。

public static async Task<List<T>> getDataListFromService<T>(string queryString)
        {
            Debug.WriteLine("###Building HttpClient for " + queryString);
            HttpClient client = new HttpClient();
            Debug.WriteLine("###Building GetAsync...");
            HttpResponseMessage response = await client.GetAsync(queryString);
            Debug.WriteLine("### HTTP Get Response: " + response.ReasonPhrase);
            List<T> data = null;
            if (response.IsSuccessStatusCode)
            {
                string json = response.Content.ReadAsStringAsync().Result;
                Debug.WriteLine("### JSON REsult: " + json);
                ITraceWriter writer = new MemoryTraceWriter();
                JsonSerializerSettings settings = new JsonSerializerSettings
                {
                    TraceWriter = writer
                };
                try
                {
                    data = JsonConvert.DeserializeObject<List<T>>(json, settings);
                }
                catch (System.Exception ex)
                {
                    Debug.WriteLine("### Exception " + ex.Message);
                    Debug.WriteLine("### Trace Results: " + writer);

                }
            }
            return data;
        }

As you already figured out, you should use a custom IReferenceResolver . 如您所想,您应该使用自定义IReferenceResolver

You asked in the comments how can it be done with multiple types. 您在评论中问到如何使用多种类型。 You can use the resolver code found here to do that. 您可以使用此处找到的解析器代码来执行此操作。 This link includes a full example: 此链接包含完整的示例:

 <script src="https://gist.github.com/carlin-q-scott/4c8a9cce734fa5b10a97.js"></script> 

Although it doesn't use multiple types, it's easy to demonstrate how it'd used in such a case. 尽管它不使用多种类型,但很容易演示在这种情况下的用法。

For example, in addition to Person , we can add a Cat type: 例如,除了Person ,我们还可以添加Cat类型:

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

then add it as a property of Person : 然后将其添加为Person的属性:

public class Person
{
  public string Name { get; set;}
  public string PhoneNumber { get; set;}
  public Person Partner { get; set;}
  public Cat Cat { get; set;}
}

and then change the json into: 然后将json更改为:

[
  {
     ""$id"": ""Jane Doe"",
    ""Name"": ""Jane Doe"",
    ""Cat"": {
     ""$id"": ""Johny"",
      ""Name"": ""Johny"",
    },
    ""PhoneNumber"": ""(555)555-5555"",
    ""Partner"": {
      ""$id"": ""John Doe"",
      ""Name"": ""John Doe"",
      ""PhoneNumber"": ""(555)555-5555"",
      ""Partner"": {
        ""$ref"": ""Jane Doe""
      },
      ""Cat"": {
         ""$ref"": ""Johny""
        }
    }
  },
  {
    ""$ref"": ""John Doe"",
  }
]

and it would work the same, as in this fiddle (note that instead of using ReferenceResolverProvider (as in the link) it uses ReferenceResolver (which is obselete), and it's because it causes some strange error here; Anyway, you should use the former). 并且它的工作原理与该提琴一样 (请注意,与其使用ReferenceResolverProvider (如链接中所示),不如使用ReferenceResolver (后者已过时),这是因为它在这里引起了一些奇怪的错误;无论如何,您应该使用前者)。

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

相关问题 Newtonsoft JSON 反序列化问题 [将值转换为类型时出错] - Newtonsoft JSON Deserialize Issue [Error converting value to type] 将字符串转换为类型时出错 - Newtonsoft JSON 反序列化 - Error converting string to type - Newtonsoft JSON deserialize C#Json反序列化异常(“将值“ id”转换为类型“ Eng_Tab.JsonData”的错误。路径“ [0]”,第1行,位置5。”) - C# Json Deserialize exception (“Error converting value ”id“ to type 'Eng_Tab.JsonData'. Path '[0]', line 1, position 5.”) 反序列化具有未知值类型的JSON - Deserialize JSON with a unknown value type 将json转换为类型时出错 - Error converting json to type C#JSON错误(将值“用户名”转换为类型时出错) - C# JSON Error (Error converting value “username” to type) 将值{null}转换为输入json中的&#39;System.DateTime&#39;类型时出错 - Error converting value {null} to type 'System.DateTime' in input json Newtonsoft.json将值333转换为类型时出错 - Newtonsoft.json Error converting value 333 to type JSON反序列化,错误:null到值类型,如何知道确切的属性导致错误? - JSON deserialize , Error : null to value type, how to know exact property causing error? JSON.NET反序列化错误转换为IList <string> - JSON.NET Deserialize Error converting to IList<string>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM