0

I am referring to the Google.Apis.Admin.Directory.directory_v1.Data.User type.

The property type of Addresses, for example, in beta versions (i.e. 1.7 and older) was

public virtual System.Collections.Generic.IList<UserAddress> Addresses { get; set; }

In later versions (currently 1.9.1), they are all of type object.

public virtual object Addresses { get; set; }

What are the reasons behind the change and usage scenarios?

I trawled the release notes, the web, google group, SO, etc. and found no explanation on this.

peleyal
  • 3,472
  • 1
  • 14
  • 25
Duoc Tran
  • 834
  • 14
  • 18
  • Can you also add the revision of the API in both cases, it looks like the API was changed (and not the core client library). So I'm asking what are xxx and yyy (1.7.0.xxx and 1.9.1.yyy)? – peleyal Apr 14 '15 at 13:17
  • The 1.7 and 1.9 versions mentioned in the question are 1.7.0.25-beta and 1.9.0.53. The change first appeared in revision 1.8.1.350, as far as I know. – Duoc Tran Apr 15 '15 at 02:57
  • @peleyal I noticed the [resource representation doc](https://developers.google.com/admin-sdk/directory/v1/reference/users) shows 2 `addresses` fields, one writable, the other not. The writable is an object array whereas the readonly `addresses` field is a string. I get the object array when testing it in the [API Explorer](https://developers.google.com/apis-explorer/#s/admin/directory_v1/directory.users.get). Same for `emails`, `phones`, etc. – Duoc Tran Apr 20 '15 at 00:49
  • As you can see in https://developers.google.com/apis-explorer/#s/discovery/v1/discovery.apis.getRest?api=admin&version=directory_v1 "addresses" property in the "user" object is defined as "any" (and not array of an object) – peleyal Apr 20 '15 at 13:37

1 Answers1

1

A change to the backend had the unintended consequence of changing the discovery document for the service, making the addresses field (and others) being marked as type=any. This causes problems for strongly types languages like .NET, as you've found. The team is aware of the issue but it's unclear when a fix will be available.

Eric Koleda
  • 12,420
  • 1
  • 33
  • 51
  • Thanks, @Eric Koleda, for the explanation. I have worked around that by deserializing it to the corresponding type, i.e. `Emails` to `List`, if it is of type `Newtonsoft.Json.Linq.JArray`. – Duoc Tran May 22 '15 at 06:48
  • @DuocTran would you mind sharing the deserialization code you're using? In place of the NuGet package I've been using a copy of the C# client source code from [https://developers.google.com/admin-sdk/directory/v1/libraries](https://developers.google.com/admin-sdk/directory/v1/libraries) modified so that the `Addresses`, `Emails`, `ExternalIds`, `Ims`, `Organizations`, `Phones`, `Relations`, and `Websites` properties have the appropriate `IList` type, but I'd like to switch back to using the NuGet package if possible. – Sean Rose Apr 29 '16 at 19:13
  • @EricKoleda do you have any update to share on if/when this may be fixed? I found two issues related to this, though both are for the Java client, and neither has seen any substantive updates: [Issue 3645](https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=3645&q=label:API-Admin): Broken code generator for Directory API in Java client: User class lacking explicit types. [Issue 3730](https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=3730&q=label:API-Admin): Latest version of the Directory API client returns Object instead of correct class. – Sean Rose Apr 29 '16 at 19:21
  • Unfortunately I don't have any updates to report. For now the situation remains non-ideal. – Eric Koleda May 02 '16 at 14:33
  • 1
    @SeanRose it's is a workaround, not an ideal solution. I check the properties and deserialize them. You might want to create extension methods to simplify the code. `if (user.Emails != null && user.Emails.GetType() == typeof(Newtonsoft.Json.Linq.JArray)) { var emails = Newtonsoft.Json.JsonConvert.DeserializeObject>(user.Emails.ToString()); }` – Duoc Tran May 02 '16 at 22:54
  • Thanks @DuocTran. I've ended up actually overwriting the relevant property with the deserialized type any time I get a User from the API, and the client still serializes it correctly for adds/updates. For example: `var externalIdsJson = user.ExternalIds as Newtonsoft.Json.Linq.JToken; if (externalIdsJson != null) { user.ExternalIds = externalIdsJson.ToObject>(); }` That still requires casting the property to the correct type any time I use it, but saves having to keep a separate copy of the list in sync with the original. – Sean Rose May 05 '16 at 23:44