【问题标题】:Unable to clear Google user property completely无法完全清除 Google 用户财产
【发布时间】:2015-03-01 20:45:18
【问题描述】:

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

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

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

我尝试使用完整的更新,也尝试使用 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 方法来查看它正在输出什么,我发现给它分配一个空字符串和一个空列表,一个带有一个空字符串的列表,一个新地址(对于例如)对象和带有新地址对象的列表都不起作用。然而,序列化程序按预期抛出了它们。

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

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

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

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

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

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

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

更新 2: 通过为 String 类型创建新的定制器,我能够获取代码以打印出包括 Null 的序列化字符串。每次运行代码时,它都会生成一个自定义的 NullToken(基本上是一个生成的 GUID,我在上面添加了一个词),它被设置为我要删除的字段的字符串值。然后,当序列化程序遇到一个字符串时,它会检查该字符串是否与 NullToken 匹配。如果是这样,我使用WriteNull() 的jsonWriter 方法。不然我就直接传给将军WriteValue()

然后我只需要自定义一系列类(传递给服务的初始化程序、作为初始化程序一部分的 NewtonsoftJsonSerializer 和添加到 NJS 设置的定制程序)并将它们设置为使用创建服务时的默认值。

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

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

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

【问题讨论】:

  • 我突然被否决的任何原因?如果是这样,我很想听听你的 cmets。

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


【解决方案1】:
  • 将以下内容传递给例如电话的数据类型:

{
  "phones": "[]"
}

【讨论】:

  • 谢谢,但不幸的是,除了 null 之外的任何东西似乎都不能从我的角度工作。我认为问题是谷歌目录 api 以及它如何序列化数据 - 删除告诉服务器删除信息所需的空值。我已经根据过去几天的发现更新了帖子。
  • 实际上,您是否验证过它有效?我有一个列出了 3 个 ims 的测试用户,我从 APIs Explorer 页面获得。如果我然后尝试将其设置为null[](在他们给出的引号内),我得到的结果就是我输入的任何内容,即使它无效(如[?)。如果我再次获取,则没有任何更新。你也这么看吗?
【解决方案2】:

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

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();

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

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

地址 = {[ { “类型”:“自定义”, “自定义类型”:“” } ]}

关系 = {[ { “类型”:“自定义” } ]}

仍在等待 Google 的回复。我已经盯着问题 3701:无法通过 Directory Admin API 删除用户属性

如果可以提供建议我愿意测试它。

【讨论】:

  • 好消息是他们至少已经对问题进行了分配和分类,希望随着它的发展,它会得到解决。感谢您的意见!
  • Google 于 2015 年 4 月 13 日作出回应: 更新:有一个确认的错误,补丁无法正常工作。但是,由于 update 遵循补丁语义(仅修改指定的属性),因此应该使用它。要传递的正确内容是 null。但是,一些客户端库存在空值问题。对于 Java,您需要使用 Data.nullOf(type) (IIRC) 创建显式空值。否则,在 JSON 序列化期间将忽略 null 值。不确定.NET 的方法是什么。最坏的情况是绕过模型类并发送原始 JSON。
【解决方案3】:

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

“Get()”的末尾不显示更新后的值。

string uri = "@987654321@";
    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");

【讨论】:

    【解决方案4】:

    通过 null 也可以:

    {
      "phones": null
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 2015-12-29
      • 2021-04-07
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 2012-01-24
      相关资源
      最近更新 更多