我正在尝试更新用户的次要信息(地址,电子邮件,外部ID,ims,电话,组织,关系 - 补丁页面上列出的数组等内容)。我成功地进行身份验证,添加新信息(一次一个或多个)并删除一个,只要它留下一个(我更新JArray,留下除我想要的那个之外的所有内容)。
因此,如果我有 3 个地址,我可以删除一两个地址,它会适当更新。我可以轻松地使用补丁来清除和更新正常信息,例如名字和姓氏,重命名用户和更新密码。
但是,如果我尝试删除所有一种类型的信息,则没有任何反应。我尝试将用户地址属性设置为空以及空列表或数组。通过调试,我已经验证了它发出的用户补丁是准确的,但服务器端似乎什么也没发生。
我也尝试使用完整更新,并再次使用空列表或空列表,但发生了同样的问题。
我需要做什么才能完全清除这些属性之一?
示例代码:
//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 源代码后,我发现我可以调用服务的序列化程序方法来查看它正在喷出什么,我发现为它分配一个空字符串、空列表、一个带有一个空字符串的列表、一个新的地址(例如)对象和一个带有新地址对象的列表都不起作用。然而,序列化者按预期扔了它们。
但是,如果我将其设置为 null,它就会被忽略。
在查看补丁语义页面时,我看到以下内容:
要删除字段,请指定该字段并将其设置为 null。例如,"注释":空。您还可以通过将整个对象设置为 null 来删除整个对象(如果它是可变的)。
查看给定的示例,他们希望数据显示{"addresses":null}
,而不是像任何其他变体(例如{"addresses":""}
,{"addresses":[]}
或{"addresses":[""]}
。
在花了一些时间深入研究 API 代码后,我能够找到他们使用的序列化程序的第 42 行,他们将序列化程序设置设置为忽略 null(例如,我假设有助于降低修补的数据量)。
这适用于大多数事情,但意味着当尝试修补或更新时,序列化程序会忽略设置为 null 的值,因此服务器看不到该条目并且不会删除它。
因此,我正在努力找出解决此问题的最佳方法。在StackOverflow上还有其他一些帖子,我将要看,希望我能够解决它(除非有人先进入它)。如果我这样做,我会发布一个答案。
更新 2:通过为 String 类型创建新的定制器,我能够获取打印出包含 Null 的序列化字符串的代码。每次运行代码时,它都会生成一个自定义的 NullToken(基本上是一个生成的 GUID,我在其中附加了一个单词),该 GUID 设置为我要删除的字段的字符串值。然后,当序列化程序命中字符串时,它会检查该字符串是否与 NullToken 匹配。如果是这样,我使用 jsonWriter 方法来WriteNull()
.否则,我只是将其传递给一般WriteValue()
.
然后,我只需要自定义一系列类(传递给服务的初始值设定项、作为初始值设定项一部分的 NewtonsoftJsonSerializer 和添加到 NJS 设置中的定制器),并在创建服务时设置这些类而不是默认值。
现在我的代码正确地抽出类似{"addresses":null}
的东西,我对此感到高兴。
不幸的是,它仍然不起作用。我在 API 资源管理器中做了更多的测试,并意识到即使返回的对象显示了您输入内容的更新,实际上也没有发生任何事情。我认为它根本没有删除,因此我为 API 本身打开了一个问题。如果事实证明是我自己的错,我会在这里给出答案。
总结:我现在相当确定问题出在谷歌API本身。
- 将以下内容传递给例如电话的数据类型:
{
"phones": "[]"
}
- 在底部进行测试:https://developers.google.com/admin-sdk/directory/v1/reference/users/update
我得到了同样的东西。 这是我的代码:
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()"仔细检查,地址和关系中的空值已消失并显示以下内容:
请记住,我在这些属性中有以前的值,现在的目标是清除我分配值之前的内容,为空。
地址 = {[ { "类型": "自定义", "自定义类型": " }]}
关系 = {[ { "类型":"自定义" }]}
仍在等待谷歌的回应。 我盯着问题 3701:无法通过目录管理 API 删除用户属性
如果可以提供建议,我愿意测试它。
使用该建议构造一个原始JSON并发送它;以下是我想出的。 这不是工作,但它也不会引发错误。 也许这对某些人来说是一个好的开始,他们可以让它发挥作用。
在末尾的"Get()"不显示更新的值。
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");
passing null OK too:
{
"phones": null
}