В UWP: свойство Contact.Phones не возвращает IList <ContactPhone>, как указано в документации - PullRequest
0 голосов
/ 26 октября 2019

В приложении UWP я выбираю контакт, используя

var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker(); Contact contact = await contactPicker.PickContactAsync();

Затем я сериализую возвращенный объект контакта, используя Json.NET , как показано ниже:

string c = JsonConvert.SerializeObject(contact);

Но проблема в том, что свойства в объекте контакта, которые (должны быть) типа IList, такие как телефоны, электронные письма, адреса и т. Д., Являютсянеправильно сериализовано. Они являются пустыми массивами JSON.

После проверки я выяснил, что проблема заключается в том, что эти свойства не возвращают объекты классов, реализующих интерфейс IList, как предполагалось! Вместо этого они возвращают объекты типа System._ComObject. Поэтому при вызове contact.Phones.GetType().FullName я получаю: System._ComObject.

И то же самое также с contact.Emails, contact.Addresses ... и т. Д.

Любая помощь, чтобы получить свойства правильнои, следовательно, правильно сериализовать контактный объект?

1 Ответ

0 голосов
/ 26 октября 2019

Большинство типов UWP на самом деле являются COM-объектами. Есть какая-то магия, заставляющая их появляться и действовать как проекции C #, на которые они претендуют, но если вы попытаетесь сделать что-то с помощью Reflection (как это делает JSON.NET), реальность поднимает свою уродливую голову.

Некоторое быстрое тестированиераскрывает две возможные опции:

1) Формирование значения, возвращенного из contactPicker.PickContactsAsync(), в реальный объект C # может быть выполнено путем запуска его через вызов LINQ .ToList() (или, я думаю, .ToArray()). Вы должны будете сделать это для каждого свойства коллекции на каждом Contact объекте, но в конце у вас будет счастливо сериализуемый объект C #.

2) Напишите свой собственный сериализатор JSON.NETдля объекта Contact, который понимает, как получить доступ и сериализовать каждое свойство индивидуально. Если вы делаете что-то вроде var singleContact = await contactPicker.pickContactAsync(), вы все равно можете делать singleContact.Addresses[0] или другие подобные списочные вещи так, как вы ожидаете в C # -коде, что означает, что написание такого сериализатора было бы очень возможным.

...