无法完全清除Google用户属性

时间:2015-01-03 22:58:45

标签: google-api google-admin-sdk google-api-dotnet-client google-directory-api

我正在尝试更新用户的辅助信息(地址,电子邮件,externalIds,即时消息,电话,组织,关系 - patch页面上列出的数组等内容)。我成功地能够进行身份验证,添加新信息(一次一个或多个)并删除一个,只要它剩下一个(我更新JArray除了我想要的一切)。

所以,如果我有3个地址,我可以删除一个或两个,并且它会适当更新。我可以轻松地使用补丁来清除和更新普通信息,如姓名,重命名用户和更新密码。

但是,如果我尝试删除所有类型的信息,则不会发生任何事情。我已经尝试将用户地址属性设置为null以及空列表或数组。通过调试,我已经验证了它发出的用户补丁是准确的,但似乎没有任何事情发生在服务器端。

我尝试使用完整更新,并再次使用空列表或空列表,但同样的问题也会发生。

如何彻底清除其中一个属性需要做什么?

示例代码:

//Try both a full user for an update and a blank user for a patch
User uRetrieved = directoryServiceDict[Domain].Users.Get(fullEmail).Execute();
User uPatch = new User();
uPatch.Addresses = null;
uRetrieved.Addresses = new List<Address>();
//try both a patch and update
directoryServiceDict[Domain].Users.Patch(uPatch, u.PrimaryEmail).Execute();
directoryServiceDict[Domain].Users.Update(uRetrieved, u.PrimaryEmail).Execute();

更新:我进行了一系列测试,试图传递任何我能做的但没有任何效果。在深入了解API源代码之后,我发现我可以调用服务的Serializer方法来查看它的输出方式,并且我发现为它分配一个空字符串,空列表,一个带有一个空字符串的列表,一个新地址(用于示例)对象和具有新Address对象的列表都不起作用。然而,序列化器按预期抛出它们。

但是,如果我将其设置为null,则会被忽略。

在查看patch semantics页面后,我看到以下内容:

  

要删除字段,请指定该字段并将其设置为null。例如,“comment”:null。您也可以通过将整个对象设置为null来删除整个对象(如果它是可变的)。

查看给定的示例,他们希望数据显示为{"addresses":null},而不是像{"addresses":""}{"addresses":[]}{"addresses":[""]}那样的任何其他变体。

花了一些时间深入研究API代码后,我找到了line 42 of the Serializer they use,他们在其中设置了序列化程序设置以忽略null(例如,我假设有助于保持较低的数据量以进行修补)。 / p>

这适用于大多数事情,但意味着在尝试修补程序或更新时,序列化程序忽略设置为null的值,因此服务器没有看到该条目,也不会删除它。

所以,我正在努力找出解决这个问题的最佳方法。 StackOverflow上有一些other posts我将要看一下,希望我能够解决它(除非有人先得到它)。如果我这样做,我会发一个答案。

更新2:我能够通过为String类型创建新的Customizer来获取打印出包含Null的序列化字符串的代码。每次运行代码时,它都会生成一个自定义的NullToken(基本上是一个生成的GUID,我在其上添加了一个单词),它被设置为我想要删除的字段的字符串值。然后,当序列化程序命中字符串时,它会检查字符串是否与NullToken匹配。如果是,我使用WriteNull()的jsonWriter方法。否则,我只是将其传递给一般WriteValue()

然后我只需要自定义一系列类(传递给服务的初始化程序,作为初始化程序的一部分的NewtonsoftJsonSerializer和添加到NJS设置的定制程序)并设置这些类而不是创建服务时的默认值。

现在我的代码正确地推出了类似{"addresses":null}的内容,我很高兴。

不幸的是它仍然不起作用。我在API资源管理器中做了一些测试,并意识到即使返回的对象显示了你输入的内容的更新,实际上也没有发生任何事情。我认为它根本没有删除,因此我有opened an issue for the API itself。如果结果证明是我自己的错,我会在这里给出答案。

摘要:我现在相当确定问题出在Google API本身。

3 个答案:

答案 0 :(得分:0)

  • 将以下内容传递给数据类型,例如手机:

{
  "phones": "[]"
}

答案 1 :(得分:0)

我得到同样的东西。这是我的代码:

User queryUser = service.Users.Get("user@domain.com").Execute();

List<UserAddress> newAddresses = new List<UserAddress>();
  UserAddress newAddress = new UserAddress{};

List<UserRelation> newRelations = new List<UserRelation>();
  UserRelation newRelation = new UserRelation{};

newAddresses.Add(newAddress);
newRelations.Add(newRelation);

queryUser.Addresses = newAddresses;
queryUser.Relations = newRelations;

User _updated = service.Users.Update(queryUser,"user@domain.com").Execute();

当我在&#34; _updated&#34;之后插入一个断点时我可以看到地址和关系为null,到目前为止一直很好。我退出应用程序并再次启动它并使用&#34; Get()&#34;在同一用户帐户上,地址和关系中的空值已消失,并显示以下内容:

****请记住,我在这些属性中有以前的值,现在的目标是在分配值之前清除内容,为空。***

地址= {[   {     &#34;输入&#34;:&#34; custom&#34;,     &#34; customType&#34;:&#34;&#34;   } ]}

关系= {[   {     &#34;键入&#34;:&#34; custom&#34;   } ]}

还在等待谷歌的回应。我已经注意到问题3701:无法通过Directory Admin API删除用户属性

如果能提出建议我愿意测试。

答案 2 :(得分:0)

使用建议构建原始JSON并发送它;以下是我想出的。它没有用,但它也没有抛出错误。也许这对某些人来说是一个好的开始,他们可以使它发挥作用。

在&#34; Get()&#34;结束时是没有显示更新的值。

string uri = "https://www.googleapis.com/admin/directory/v1/users/user@domain.com";
    var request = (HttpWebRequest) HttpWebRequest.Create(uri);
    request.Method = "PATCH";
    request.Accept = "application/json";
    request.Headers.Add("Authorization", "Bearer " + GoogleToken.getToken() );
    using(StreamWriter writer = new StreamWriter(request.GetRequestStream()))
    {
    writer.Write("{ \"addresses\": [ { null } ] }");
    writer.Flush();
    writer.Close();
    }
     
    WebResponse response = request.GetResponse();
    Stream stream = response.GetResponseStream();
    string json = "";
    using (StreamReader reader = new StreamReader(stream))
    {
    while(!reader.EndOfStream)
    {
    json += reader.ReadLine() + '\n';
    }
    }
    Debug.WriteLine("JSON: " + json);
     
    User Result = GoogleToken.GoogleService().Users.Get("user@domain.com").Execute();
    Debug.WriteLine("Application Done");