使用 Http 和 jwt Xamarin Forms 获取 NullReferenceException 的问题 Android
Issue getting NullReferenceException using Http with jwt Xamarin Forms Android
所以我的代码在 PostMan 中工作,查询 api 以在我的 Android 应用程序中本地填充列表视图。但是当我从应用程序中 运行 它时,我在行 "Items.Clear() in ShipViewModel.cs
上得到 NullReferenceException
我尝试对地址进行硬编码而不是使用我的 APIQueriable 路径,我尝试生成新的 JWT,我尝试手动清理我的 /bin /obj 文件夹以排除代码编译不正确。
ShipsViewModel.cs Xamarin.Forms/ViewModels
{
private GallogClient _gallogClient;
public ObservableCollection<ShipCatalog> Items { get; set; }
public Command LoadItemsCommand { get; }
public ShipsViewModel()
{
Title = "Ships";
_gallogClient = new GallogClient("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuZ2FsbG9nLmNvIiwiYXVkIjoiaHR0cDpcL1wvYXBpLmdhbGxvZy5jbyIsImlhdCI6MTM1Njk5OTUyNCwibmJmIjoxMzU3MDAwMDAwLCJkYXRhIjp7ImlkIjo1NywidXNlcm5hbWUiOiJQYXJhIiwiaGFuZGxlIjoiUGFyYSIsImVtYWlsIjoicGFyYWJvbGE5NDlAZ21haWwuY29tIn19.bRpI9hVy-Spky5pbZhJCkyN-MT9RA6ap_yD9ezRxCxo");
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand(), () => !IsBusy);
}
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
LoadItemsCommand.ChangeCanExecute();
Items.Clear();
var items = await _gallogClient.GetItemsAsync<ShipList>();
foreach (var item in items.ships.ToList())
{
Items.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
}
GallogClient.cs Gallog.API
{
internal readonly HttpClient Client = new HttpClient { BaseAddress = new Uri("https://api.gallog.co/api/") };
public string Jwt { get; set; }
public GallogClient()
{
}
public GallogClient(string jwt)
{
Jwt = jwt;
}
private StringContent JwtContent
{
get {
return new StringContent(JsonConvert.SerializeObject(new
{
jwt = Jwt
}), Encoding.UTF8, "application/json");
}
}
//...
public async Task<T> GetItemAsync<T>(string name) where T : ApiQueryable
{
return await PostAsync<T>($"{GetPath<T>()}/{name}");
}
public async Task<T> GetItemsAsync<T>() where T : ApiQueryable
{
return await PostAsync<T>($"{GetPath<T>()}");
}
internal string GetPath<T>()
{
if (typeof(T).GetCustomAttributes(
typeof(ApiPathAttribute), true
).FirstOrDefault() is ApiPathAttribute at)
{
return at.Path;
}
return null;
}
public async Task<T> PostAsync<T>(string path) where T : ApiQueryable
{
var response = await Client.PostAsync(path, JwtContent);
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
public async Task<T> PostAsync<T>(object body, string path) where T : ApiQueryable
{
var response = await Client.PostAsync(path,
new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"));
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
}
}
ShipList.cs Xamarin.Forms/Models
{
[ApiPath("ships")]
public class ShipList : ApiQueryable
{
public ShipCatalog[] ships { get; set; }
}
public class ShipCatalog
{
public int id { get; set; }
public string name { get; set; }
// ...etc etc
}
}
Items
为空,因为您声明了它但从未对其进行初始化
public ShipsViewModel()
{
...
Items = new ObservableCollection<ShipCatalog>();
...
}
所以我的代码在 PostMan 中工作,查询 api 以在我的 Android 应用程序中本地填充列表视图。但是当我从应用程序中 运行 它时,我在行 "Items.Clear() in ShipViewModel.cs
上得到 NullReferenceException我尝试对地址进行硬编码而不是使用我的 APIQueriable 路径,我尝试生成新的 JWT,我尝试手动清理我的 /bin /obj 文件夹以排除代码编译不正确。
ShipsViewModel.cs Xamarin.Forms/ViewModels
{
private GallogClient _gallogClient;
public ObservableCollection<ShipCatalog> Items { get; set; }
public Command LoadItemsCommand { get; }
public ShipsViewModel()
{
Title = "Ships";
_gallogClient = new GallogClient("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuZ2FsbG9nLmNvIiwiYXVkIjoiaHR0cDpcL1wvYXBpLmdhbGxvZy5jbyIsImlhdCI6MTM1Njk5OTUyNCwibmJmIjoxMzU3MDAwMDAwLCJkYXRhIjp7ImlkIjo1NywidXNlcm5hbWUiOiJQYXJhIiwiaGFuZGxlIjoiUGFyYSIsImVtYWlsIjoicGFyYWJvbGE5NDlAZ21haWwuY29tIn19.bRpI9hVy-Spky5pbZhJCkyN-MT9RA6ap_yD9ezRxCxo");
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand(), () => !IsBusy);
}
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
LoadItemsCommand.ChangeCanExecute();
Items.Clear();
var items = await _gallogClient.GetItemsAsync<ShipList>();
foreach (var item in items.ships.ToList())
{
Items.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
}
GallogClient.cs Gallog.API
{
internal readonly HttpClient Client = new HttpClient { BaseAddress = new Uri("https://api.gallog.co/api/") };
public string Jwt { get; set; }
public GallogClient()
{
}
public GallogClient(string jwt)
{
Jwt = jwt;
}
private StringContent JwtContent
{
get {
return new StringContent(JsonConvert.SerializeObject(new
{
jwt = Jwt
}), Encoding.UTF8, "application/json");
}
}
//...
public async Task<T> GetItemAsync<T>(string name) where T : ApiQueryable
{
return await PostAsync<T>($"{GetPath<T>()}/{name}");
}
public async Task<T> GetItemsAsync<T>() where T : ApiQueryable
{
return await PostAsync<T>($"{GetPath<T>()}");
}
internal string GetPath<T>()
{
if (typeof(T).GetCustomAttributes(
typeof(ApiPathAttribute), true
).FirstOrDefault() is ApiPathAttribute at)
{
return at.Path;
}
return null;
}
public async Task<T> PostAsync<T>(string path) where T : ApiQueryable
{
var response = await Client.PostAsync(path, JwtContent);
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
public async Task<T> PostAsync<T>(object body, string path) where T : ApiQueryable
{
var response = await Client.PostAsync(path,
new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"));
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
}
}
ShipList.cs Xamarin.Forms/Models
{
[ApiPath("ships")]
public class ShipList : ApiQueryable
{
public ShipCatalog[] ships { get; set; }
}
public class ShipCatalog
{
public int id { get; set; }
public string name { get; set; }
// ...etc etc
}
}
Items
为空,因为您声明了它但从未对其进行初始化
public ShipsViewModel()
{
...
Items = new ObservableCollection<ShipCatalog>();
...
}