Xamarin Forms、HttpClient class - GetStringAsync 和 GetAsync return 空值并快速退出函数
Xamarin Forms, HttpClient class - GetStringAsync and GetAsync return null value and exit from function quickly
当我运行我的代码时,在调用 GetStringAsync 或 GetAsync 的函数中,这 2 个调用 returns 空值并立即退出我的函数(之后的所有代码都未到达)
我制作了一个可以从网络浏览器访问的网络 api (url reached on browser) , also in the emulator browser ( Browser on the Android Emulator ) 然后我尝试制作一个能够与之通信的 xamarin 表单
class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainPageViewModel()
{
GetEmployees();
}
private async void GetEmployees()
{
using (var httpClient = new HttpClient())
{
var uri = "http://192.168.1.135:8092/api/Masters/GetEmployees/";
var result = await httpClient.GetStringAsync(uri);
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(result);
Employees = new ObservableCollection<Employee>(EmployeeList);
}
}
ObservableCollection<Employee> _employees;
public ObservableCollection<Employee> Employees
{
get
{
return _employees;
}
set
{
_employees = value;
OnPropertyChanged(nameof(Employee));
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
或
class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private const string ApiBaseAddress = "http://192.168.1.135:8092/api/Masters/GetEmployees/";
public MainPageViewModel()
{
GetEmployees();
}
private HttpClient CreateClient()
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(ApiBaseAddress)
};
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
private async void GetEmployees()
{
using (var httpClient = CreateClient())
{
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
var test = response;
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(json))
{
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(json);
Employees = new ObservableCollection<Employee>(EmployeeList);
}
}
response.Dispose();
}
}
ObservableCollection<Employee> _employees;
public ObservableCollection<Employee> Employees
{
get
{
return _employees;
}
set
{
_employees = value;
OnPropertyChanged(nameof(Employee));
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我希望 var result = await httpClient.GetStringAsync(uri);
或
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
returns 但实际输出为 null 并且未到达后面的代码,因为这 2 个调用立即从函数中退出
避免混合 async/await 和阻塞调用,例如 .Wait() 或 .Result
重构您的代码,使其始终保持异步。
public MainPageViewModel()
{
var EmployeeList = GetEmployees();
Employees = new ObservableCollection<Employee>(EmployeeList.Result);
}
private async Task<List<Employee>> GetEmployees()
{
using (var httpClient = CreateClient())
{
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
var test = response;
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(json))
{
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(json);
return EmployeeList;
}
}
return null;
}
}
当我运行我的代码时,在调用 GetStringAsync 或 GetAsync 的函数中,这 2 个调用 returns 空值并立即退出我的函数(之后的所有代码都未到达)
我制作了一个可以从网络浏览器访问的网络 api (url reached on browser) , also in the emulator browser ( Browser on the Android Emulator ) 然后我尝试制作一个能够与之通信的 xamarin 表单
class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainPageViewModel()
{
GetEmployees();
}
private async void GetEmployees()
{
using (var httpClient = new HttpClient())
{
var uri = "http://192.168.1.135:8092/api/Masters/GetEmployees/";
var result = await httpClient.GetStringAsync(uri);
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(result);
Employees = new ObservableCollection<Employee>(EmployeeList);
}
}
ObservableCollection<Employee> _employees;
public ObservableCollection<Employee> Employees
{
get
{
return _employees;
}
set
{
_employees = value;
OnPropertyChanged(nameof(Employee));
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
或
class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private const string ApiBaseAddress = "http://192.168.1.135:8092/api/Masters/GetEmployees/";
public MainPageViewModel()
{
GetEmployees();
}
private HttpClient CreateClient()
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(ApiBaseAddress)
};
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
}
private async void GetEmployees()
{
using (var httpClient = CreateClient())
{
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
var test = response;
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(json))
{
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(json);
Employees = new ObservableCollection<Employee>(EmployeeList);
}
}
response.Dispose();
}
}
ObservableCollection<Employee> _employees;
public ObservableCollection<Employee> Employees
{
get
{
return _employees;
}
set
{
_employees = value;
OnPropertyChanged(nameof(Employee));
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我希望 var result = await httpClient.GetStringAsync(uri);
或
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
returns 但实际输出为 null 并且未到达后面的代码,因为这 2 个调用立即从函数中退出
避免混合 async/await 和阻塞调用,例如 .Wait() 或 .Result
重构您的代码,使其始终保持异步。
public MainPageViewModel()
{
var EmployeeList = GetEmployees();
Employees = new ObservableCollection<Employee>(EmployeeList.Result);
}
private async Task<List<Employee>> GetEmployees()
{
using (var httpClient = CreateClient())
{
var response = await httpClient.GetAsync(ApiBaseAddress).ConfigureAwait(false);
var test = response;
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(json))
{
var EmployeeList = JsonConvert.DeserializeObject<List<Employee>>(json);
return EmployeeList;
}
}
return null;
}
}