【发布时间】:2019-08-18 10:04:35
【问题描述】:
我在 Xamarin.Forms 应用程序中向 google 进行身份验证。一旦通过身份验证,我想检索用户电子邮件,并使用我改编自 this blog 的代码,用于检索电子邮件的代码:
public class GoogleProfile
{
[Preserve]
[JsonConstructor]
public GoogleProfile() { }
public string sub { get; set; }
public string name { get; set; }
public string given_name { get; set; }
public string profile { get; set; }
public string picture { get; set; }
public string email { get; set; }
public string email_verified { get; set; }
public string locale { get; set; }
}
public class GoogleService
{
public async Task<string> GetEmailAsync(string tokenType, string accessToken)
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(tokenType, accessToken);
var json = await httpClient.GetStringAsync("https://www.googleapis.com/oauth2/v3/userinfo");//https://www.googleapis.com/userinfo/email?alt=json");
var profile = JsonConvert.DeserializeObject<GoogleProfile>(json);
return profile.email;
}
}
现在,在最后一行 return profile.email 中有一个断点,我已经“看到”了这样的 json 文件:
{
"sub": "",
"name": "",
"given_name": "",
"profile": "",
"picture": "",
"email": "",
"email_verified": "",
"locale": "",
}
引号之间显然是数据。
我不是很习惯 JSon 但是阅读this 我认为格式只是"nameOfProperty":"ValueOfProperty",所以我做了GoogleProfile 对象。
我也读到[Preserve] 和[JsonConstructor] 属性是必需的,因此链接器在编译时不只是“删除”空的构造函数。
没有异常,也没有明显的问题,但是如果我在最后一行 return profile.email; 下放一个断点,我可以看到 json 对象包含所有数据并且非常好,但是 profile 对象有仅 email 属性值为null...
我不明白:其他属性发生了什么?甚至可能吗?你知道,你用一堆属性编写了一个对象,但创建的对象只有其中一个属性吗?如果该对象的所有属性的值为 null,则可以,但是其他属性到哪里去了?
为了确定,我已经清理并重建了项目和解决方案,我删除了 bin 和 obj 文件夹,然后再次清理并重建......我已经完成了显而易见的事情。
问题是,正如您在我之前提到的博客中看到的那样,首先我没有使用GoogleProfile 对象,我只是复制了博客中的对象......只有一个名为email 的属性。视觉工作室或xamarin或其他东西是否有可能被窃听并且更改没有得到反映?我对此表示怀疑,因为我已经更改了 GetStringAsync 方法中使用的 URI,它确实得到了反映,但是我不知道。
PD:与此同时,我将 JSON 直接解析为普通字符串,它是一个简单的对象,我只需要电子邮件,但是,如果我不得不以这种方式解析它,那就太可惜了而不是仅仅反序列化它。
编辑: 正如皮肤在我使用过的 cmets 中所建议的那样http://jsonutils.com/
其中一个属性是 bool(当然),所以我更改了它,现在的对象是:
public class GoogleProfile
{
[Preserve]
[JsonConstructor]
public GoogleProfile() { }
public string sub { get; set; }
public string name { get; set; }
public string given_name { get; set; }
public string profile { get; set; }
public string picture { get; set; }
public string email { get; set; }
public bool email_verified { get; set; }
public string locale { get; set; }
}
但这并没有改变结果,仍然发生同样的事情。断点处的结果图片:
【问题讨论】:
-
???那么示例 POCO GoogleProfile 没有 API 调用返回的所有其他属性?为什么需要解析 JSON 字符串? JSONConvert.Deserialize
应该为您完成工作,并将所有属性值放在您的 POCO 类对象中。您是否在 var profile = JsonConvert.DeserializeObject<GoogleProfile>(json);设置了断点并检查了变量json的值?它有电子邮件地址吗?如果不是,它将被设置为 null。 -
是的,正如我在问题中所说的那样。使用断点检查变量
json的值,并且与我在问题中编写的示例完全相同,但引号之间的值正确......然后我进行 json 反序列化和对象profile仅使用创建一个名为email的属性值为 null。 -
您是否尝试过添加其余属性以便反序列化所有这些属性?也许试试看。
-
对不起,我不明白“在其余属性中添加”。所有属性都编码在对象中,并检索到 json 中的所有值。我是一个业余爱好者,我没有用过那么多 JSON,也许你指的是我不知道的东西。我只是想如果文本文件有一个与对象属性名称匹配的标签,反序列化器会将这些值应用于正确的属性而无需进一步编码。
-
获取你的 json,去 jsonutils.com 让它为你创建类。
标签: c# json xamarin.forms google-oauth xamarin.auth