使用GetAsync调用Web服务时出现NullReferenceException

时间:2016-07-08 10:39:20

标签: c# wpf async-await asp.net-web-api2

我想从异步方法内部调用异步Web服务方法,并使用WPF窗口来询问用户的用户名和密码。

守则看起来与此相似:

private async Task GetUsers()
{
        List<User> users = new List<User>();

        using (var client = new HttpClient())
        {
            var authenticationWindow = new AuthenticateWindow();
            authenticationWindow.ShowDialog();

             //... Code to get the token ...
            var token = "myToken";

            client.BaseAddress = new Uri("http://localhost:56057/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);

            var response = await client.GetAsync("api/users/");

            if (response.IsSuccessStatusCode)
            {
                users = await response.Content.ReadAsAsync<List<User>>();
            }
            else if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                throw new UnauthorizedAccessException();
            }
        }

        foreach(var user in users)
        {
        }
}

如果我执行此代码,我会收到以下异常:

An unhandled exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll

调用client.GetAsync(“api / users /”)时会发生这种情况。它可能与上下文切换有关,因为我打开了窗口。

我该如何解决这个问题?

调用堆栈只显示“外部代码”。

如果我删除以下两行,一切正常:

var authenticationWindow = new AuthenticateWindow();
authenticationWindow.ShowDialog();

1 个答案:

答案 0 :(得分:2)

您正在实例化一个UI元素并在服务范围内使用,请尝试将这两个元素彼此分开。听起来你需要在AuthenticateWindow中使用这种逻辑来请求用户,也许是在Loaded事件中:

// Safe UI entry point for async work, i.e.; event handler.
async void OnLoaded(object sender, RoutedEventArgs e)
{
    var users = await GetUsersAsync();
    // Take action on the user's from the API.
}

然后让GetUsers(更适合更改为GetUsersAsync)只关注使用HttpClient和相应的API,实现并返回List<User>,如下所示:< / p>

async Task<List<User>> GetUsersAsync()
{
    List<User> users = new List<User>();

    using (var client = new HttpClient())
    {
         //... Code to get the token ...
        var token = "myToken";

        client.BaseAddress = new Uri("http://localhost:56057/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);

        var response = await client.GetAsync("api/users/");

        if (response.IsSuccessStatusCode)
        {
            users = await response.Content.ReadAsAsync<List<User>>();
        }
        else if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            throw new UnauthorizedAccessException();
        }
    }
    return users;
}