反序列化 Google 配置文件响应时出现问题
Problem deserializing Google profile response
我正在 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
我 "seen" json 文件是这样的:
{
"sub": "",
"name": "",
"given_name": "",
"profile": "",
"picture": "",
"email": "",
"email_verified": "",
"locale": "",
}
显然,引号之间是数据。
我不是很习惯JSon但是看this我觉得格式就是"nameOfProperty":"ValueOfProperty"
,所以我做了GoogleProfile
对象。
我也读到属性 [Preserve]
和 [JsonConstructor]
是必需的,因此链接器在编译时不只是 "remove" 清空构造函数。
没有异常,也没有明显的问题,但如果我在最后 return profile.email;
行放置一个断点,我可以看到 json
对象拥有所有数据并且完全没问题,但是profile
对象只有 email
属性 的值为 null
...
我不明白:其他属性怎么了?有可能吗?您知道,您使用一堆属性编写一个对象,但创建该对象时只使用其中一个属性吗?如果对象的所有属性的值为null,OK,但是其他属性去哪了?
可以肯定的是,我已经清理并重建了项目和解决方案,删除了 bin
和 obj
文件夹,然后再次清理并重建...我已经完成了显而易见的事情。
事情是,正如你在我之前提到的博客中看到的那样,首先我没有使用 GoogleProfile
对象,我只是复制了博客中的对象......只有一个 属性 称为 email
。是否有可能 visual studio 或 xamarin 或其他东西被窃听并且更改没有得到反映?我对此表示怀疑,因为我已经更改了 GetStringAsync
方法中使用的 URI,它确实得到了反映,但是,我不知道。
PD:与此同时,我将 JSON 直接解析为普通字符串,它是一个简单的对象,我只真正需要电子邮件,但是,我会很遗憾必须以这种方式解析它,而不是仅仅反序列化它。
编辑:
正如 Skin 在评论中所建议的那样,我使用了 http://jsonutils.com/
其中一个属性是布尔值(当然),所以我更改了它,对象现在是:
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; }
}
但是并没有改变结果,还是老样子。断点处的结果图像:
我认为您的代码没有任何问题。我使用了与您相同的代码,但没有进行任何更改。我使用自己的 tokenType
和 accessToken
。
我的步数:
- 将您的代码复制到我的项目中。
- 使用blog
中的项目获取我自己的token
- 安装
newtonsoft
Nuget 包
- 运行 项目并得到结果
那么,您的账户有问题吗?你的帐户有电子邮件吗?和我的有什么区别吗?
这是我得到的:
代码:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
testAsync();
}
public async Task testAsync()
{
GoogleService googleS = new GoogleService();
// use your token here
var email = await googleS.GetEmailAsync("", "");
Console.WriteLine(email);
}
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("Bearer", 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);
Console.WriteLine(json);
Console.WriteLine(profile);
return profile.email;
}
}
}
我正在 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
我 "seen" json 文件是这样的:
{
"sub": "",
"name": "",
"given_name": "",
"profile": "",
"picture": "",
"email": "",
"email_verified": "",
"locale": "",
}
显然,引号之间是数据。
我不是很习惯JSon但是看this我觉得格式就是"nameOfProperty":"ValueOfProperty"
,所以我做了GoogleProfile
对象。
我也读到属性 [Preserve]
和 [JsonConstructor]
是必需的,因此链接器在编译时不只是 "remove" 清空构造函数。
没有异常,也没有明显的问题,但如果我在最后 return profile.email;
行放置一个断点,我可以看到 json
对象拥有所有数据并且完全没问题,但是profile
对象只有 email
属性 的值为 null
...
我不明白:其他属性怎么了?有可能吗?您知道,您使用一堆属性编写一个对象,但创建该对象时只使用其中一个属性吗?如果对象的所有属性的值为null,OK,但是其他属性去哪了?
可以肯定的是,我已经清理并重建了项目和解决方案,删除了 bin
和 obj
文件夹,然后再次清理并重建...我已经完成了显而易见的事情。
事情是,正如你在我之前提到的博客中看到的那样,首先我没有使用 GoogleProfile
对象,我只是复制了博客中的对象......只有一个 属性 称为 email
。是否有可能 visual studio 或 xamarin 或其他东西被窃听并且更改没有得到反映?我对此表示怀疑,因为我已经更改了 GetStringAsync
方法中使用的 URI,它确实得到了反映,但是,我不知道。
PD:与此同时,我将 JSON 直接解析为普通字符串,它是一个简单的对象,我只真正需要电子邮件,但是,我会很遗憾必须以这种方式解析它,而不是仅仅反序列化它。
编辑: 正如 Skin 在评论中所建议的那样,我使用了 http://jsonutils.com/
其中一个属性是布尔值(当然),所以我更改了它,对象现在是:
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; }
}
但是并没有改变结果,还是老样子。断点处的结果图像:
我认为您的代码没有任何问题。我使用了与您相同的代码,但没有进行任何更改。我使用自己的 tokenType
和 accessToken
。
我的步数:
- 将您的代码复制到我的项目中。
- 使用blog 中的项目获取我自己的token
- 安装
newtonsoft
Nuget 包 - 运行 项目并得到结果
那么,您的账户有问题吗?你的帐户有电子邮件吗?和我的有什么区别吗?
这是我得到的:
代码:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
testAsync();
}
public async Task testAsync()
{
GoogleService googleS = new GoogleService();
// use your token here
var email = await googleS.GetEmailAsync("", "");
Console.WriteLine(email);
}
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("Bearer", 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);
Console.WriteLine(json);
Console.WriteLine(profile);
return profile.email;
}
}
}