【问题标题】:Xamarin Forms, HttpClient class - GetStringAsync and GetAsync return null value and exit from function quicklyXamarin Forms,HttpClient 类 - GetStringAsync 和 GetAsync 返回空值并快速退出函数
【发布时间】:2019-08-12 07:05:05
【问题描述】:

当我运行我的代码时,在调用 GetStringAsync 或 GetAsync 的函数中,这 2 个调用返回 null 值并立即退出我的函数(之后的所有代码都未到达)

我制作了一个可从网络浏览器 (url reached on browser) 访问的网络 api,也在模拟器浏览器 (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);

返回一些东西,但实际输出为空,之后的代码未到达,因为这 2 个调用立即从函数中退出

【问题讨论】:

  • 您是否尝试使用浏览器访问该网址?
  • 是的,我已经说过在浏览器上它可以工作,不幸的是,它不能用在调用上
  • 也许您正在运行的模拟器(Android 或 iOS)无法访问该网址,您可以启动您的模拟器,使用已安装的浏览器并尝试输入该网址吗?
  • 在设备浏览器中尝试 URL。
  • 使用 (var httpClient = CreateClient()) 是错误的,HttpClient 旨在为每个应用程序实例化一次,而不是每次使用。 docs.microsoft.com/en-us/dotnet/api/…

标签: c# xamarin httpclient system.net.httpwebrequest


【解决方案1】:

避免混合 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;
    }

}

【讨论】:

  • 抛出异常:不允许到 192.168.1.135 的明文 HTTP 流量
  • 我已经读过了,但对我来说不起作用。我相信我的问题是 ssl 证书,因为如果我尝试使用 https 连接到 web api,我不能
  • 您是否尝试更改其他网址?
  • 好的,将这几行代码添加到AndroidManifest.xml中问题解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 2021-04-18
  • 2021-04-30
相关资源
最近更新 更多