JSON десериализуетобъект список объектов всегда null - PullRequest
0 голосов
/ 26 мая 2018

У меня проблема с десериализацией строки JSON в класс RootObject со свойством 1 строка и списком пользовательских объектов.

Когда я отлаживаю приложение и код десериализует json, я получаю, что мое свойство ErrorCode, «test», заполняется в классе RootObject, но свойство meet всегда имеет значение 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;
        }
    }
}

РЕДАКТИРОВАТЬ:

IВнесены некоторые незначительные изменения, предложенные ниже.

Моя строка Json теперь такая:

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

Мои классы ниже.Стоит отметить, что они определены в пространстве имён «моделей» в отдельном файле кода, который выполняет десериализацию.

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"
}}

edit 3:

Я только что наткнулся на этот пост, в котором объясняетсямного!Похоже, xamarin.forms имеет известную проблему с отражением, поэтому некоторые пакеты могут работать некорректно.

JsonConvert.SerializeObject всегда возвращает {} в XamarinForms

Кто-нибудьиметь представление о том, почему это происходит и когда это будет решено.Также обходной путь, который я мог бы реализовать, чтобы я мог использовать отладку.Спасибо.

1 Ответ

0 голосов
/ 26 мая 2018
{"meets": [
{
  "VenueName": "O2"
},
{
  "VenueName": "wembly"
},
{
  "VenueName": "NEC"
}  ],  
"ErrorCode": "test"}

Ваша проблема в том, что у вас есть объект с именем "meet" в javascript, а в вашем объекте в C # у вас есть "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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...