JSON反序列化对象对象列表始终为null

时间:2018-05-26 00:26:44

标签: c# json xamarin json.net

我有一个问题是将JSON字符串反序列化为RootObject类,其中包含1个字符串属性和一个自定义对象列表。

当我调试应用程序并且代码反序列化json时,我得到了我的错误代码'属性," test",填充在RootObject课程中,但是'遇到'属性始终为null

代码目前位于跨平台的Xamarin表单应用程序中,但是我已经将代码和类定义拉出来并在一个简单的控制台应用程序中运行它们,该应用程序首次运行时没有任何问题。我正在努力弄清楚我做错了什么。

我的简单JSON对象如下:

{"meets": [
    {
      "VenueName": "O2"
    },
    {
      "VenueName": "wembly"
    },
    {
      "VenueName": "NEC"
    }
  ],
  "ErrorCode": "test"}

我的班级定义:

[JsonObject(Id = "Meets")]
public class Meets
{
    [JsonProperty(PropertyName = "VenueName")]
    public string VenueName { get; set; }
}

public class RootObject
{
    public List<Meets> Meets { get; set; }
    public string ErrorCode { get; set; }
}

命中api并获取json对象的代码(该代码被删除,其中有一个较小的简单对象):

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using EliteNfcBet.Models;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace EliteNfcBet.ViewModels
{
    public class ItemsViewModel : BaseViewModel
    {
        public ObservableCollection<Meets> RaceMeets { get; set; }
        public Command LoadItemsCommand { get; set; }

        public ItemsViewModel   ()
        {
            Title = "Select Meeting";
            RaceMeets = new ObservableCollection<Meets>();
            LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());                       
        }

        async Task ExecuteLoadItemsCommand()
        {
            if (IsBusy)
                return;

            IsBusy = true;

            try
            {
                RaceMeets.Clear();
                var result = await GetMeetingsAsync();
                //RaceMeets = result;
                //foreach (var meet in meets.Meets)
                //{
                //    RaceMeets.Add(meet);
                //}
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }

        public static async Task<RootObject> GetMeetingsAsync()
        {
            RootObject meet = new RootObject();
            //List<Meet> meets = new List<Meet>();
            HttpClient client = new HttpClient();
            client.MaxResponseContentBufferSize = 256000;

            var uri = new Uri(string.Format(Constants.RestUrl, string.Empty) + "/api/GetAvailablemeetings");

            try
            {
                var response = await client.GetAsync(uri);
                if (response.IsSuccessStatusCode)
                {
                    //var content = await response.Content.ReadAsStringAsync();
                    var content = "{\"meets\":[{\"VenueName\":\"O2\"},{\"VenueName\":\"wembly\"},{\"VenueName\":\"NEC\"}],\"ErrorCode\":\"test\"}";

                    if (!string.IsNullOrEmpty(content))
                    {

                        ITraceWriter traceWriter = new MemoryTraceWriter();

                        var settings = new JsonSerializerSettings
                        {
                            Error = (sender, args) =>
                            {
                                if (System.Diagnostics.Debugger.IsAttached)
                                {
                                    System.Diagnostics.Debugger.Break();
                                }
                            },
                            TraceWriter = traceWriter
                        };

                        //result = JsonConvert.DeserializeObject<T>(json, settings);
                        meet = JsonConvert.DeserializeObject<RootObject>(content, settings);
                        Console.WriteLine(traceWriter);
                    }

                    //if (meets.Count > 0)
                    //{
                    //    meet.MeetList = meets;
                    //}
                }
            }
            catch (Exception ex)
            {
                meet.ErrorCode = "INTERNAL_ERROR";
            }

            return meet;
        }
    }
}

修改

我做了一些小改动,建议如下。

我的Json字符串现在是这样的:

"{\"Meets\":[{\"VenueName\":\"O2\"},{\"VenueName\":\"wembly\"},{\"VenueName\":\"NEC\"}],\"ErrorCode\":\"test\"}"

我的课程如下。有一点需要注意的是,它们是在一个&#39;模型中定义的。正在进行反序列化的单独代码文件中的命名空间。

namespace EliteNfcBet.Models
{
public class Meets
{
    public string VenueName { get; set; }
}

public class RootObject
{
    public List<Meets> Meets { get; set; }
    public string ErrorCode { get; set; }
}

}

再次反序列化时我有调试输出,看起来它指向未找到Meets类成员的事实?

{2018-05-28T23:12:22.987 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets', line 1, position 9.
2018-05-28T23:12:22.993 Info Started deserializing System.Collections.Generic.List`1[[NInterpret.InterpretedObject, NInterpret.Xamarin.Droid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Path 'Meets', line 1, position 10.
2018-05-28T23:12:22.994 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[0].VenueName', line 1, position 23.
2018-05-28T23:12:22.994 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[0].VenueName', line 1, position 23.
2018-05-28T23:12:22.994 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[0]', line 1, position 28.
2018-05-28T23:12:22.995 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[1].VenueName', line 1, position 42.
2018-05-28T23:12:22.995 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[1].VenueName', line 1, position 42.
2018-05-28T23:12:22.996 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[1]', line 1, position 51.
2018-05-28T23:12:22.997 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[2].VenueName', line 1, position 65.
2018-05-28T23:12:22.997 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[2].VenueName', line 1, position 65.
2018-05-28T23:12:22.997 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[2]', line 1, position 71.
2018-05-28T23:12:22.998 Info Finished deserializing System.Collections.Generic.List`1[[NInterpret.InterpretedObject, NInterpret.Xamarin.Droid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Path 'Meets', line 1, position 72.
2018-05-28T23:12:23.009 Info Finished deserializing EliteNfcBet.Models.RootObject. Path '', line 1, position 92.
2018-05-28T23:12:23.009 Verbose Deserialized JSON: 
{
  "Meets": [
    {
      "VenueName": "O2"
    },
    {
      "VenueName": "wembly"
    },
    {
      "VenueName": "NEC"
    }
  ],
  "ErrorCode": "test"
}}

编辑3:

我刚发现这篇文章解释了很多!似乎xamarin.forms有一个已知的问题,目前有反射,所以某些包可能无法正常工作。

JsonConvert.SerializeObject always return {} in XamarinForms

有没有人知道为什么会发生这种情况以及什么时候解决这个问题。还有一个我可以实现的工作,所以我可以使用调试。感谢。

1 个答案:

答案 0 :(得分:0)

{"meets": [
{
  "VenueName": "O2"
},
{
  "VenueName": "wembly"
},
{
  "VenueName": "NEC"
}  ],  
"ErrorCode": "test"}

你的问题是你在javascript中有一个名为“meet”的对象,而在C#中的对象中你有“Meets”。将其更改为“Meets”,它应该有效。

我相信你也不需要JsonObject属性。 .NET应该能够自动处理来自JSON的序列化:

public class Meets
{
    public string VenueName { get; set; }
}

public class RootObject
{
    public List<Meets> Meets { get; set; }
    public string ErrorCode { get; set; }
}

花一些时间查看这些资源,以了解您的错误发生的原因:

https://docs.microsoft.com/en-us/dotnet/standard/serialization/

修改

以上类生成以下json:

Meets: 

{
  "VenueName": null
}

Root Object:

{
  "Meets": [
{
  "VenueName": null
}, 
{
  "VenueName": null
},
{
  "VenueName": null
}
],
  "ErrorCode": null
}