用于调用REST服务的HTTPClient无法正常工作

时间:2014-05-13 14:27:24

标签: c# rest windows-phone-8 windows-phone async-await

我正在尝试使用REST服务,它以JSON格式返回数据。我使用简单的逻辑。但代码卡在了线上。我已经从模拟器和Device中检查了这段代码。 var response = await httpClient.SendAsync(request);

这是我的代码

public async Task<string> GetMyData(string urlToCall)
        {    
            using (HttpClient httpClient = new HttpClient())
            {                    
                HttpRequestMessage request = new HttpRequestMessage(System.Net.Http.HttpMethod.Get, urlToCall);
                var response = await httpClient.SendAsync(request);
                var responseString = await response.Content.ReadAsStringAsync();
                return responseString;
            }
        }

并且呼叫就像,

string result = GetMyData(url).Result;

我错过了什么吗?我希望同步获取数据,而不是WebClient,我选择HTTPClient进行同步数据调用。

任何人都可以建议我任何解决方案。

修改

感谢@Mike Richards指出我正确的方向 我想实现如下流程,

从Main.xaml.cs调用aunticateuser() - &gt;在Process Class中调用aunticateuser()方法 - &gt;一旦响应从服务返回控制返回到Main.xaml.cs - &gt; naviagate到另一个页面,即Dashboard.xaml

但是在实际情况下它的工作方式是,在Process Class中调用aunticateuser()方法并将其发送请求到服务并返回Main.xaml.cs但不等待那里听取响应所以我将如何决定这个用户是否有效,直到我收到回复?

代码

    private void ApplicationBarDone_Click(object sender, EventArgs e)
            {
                bool isValid = checkForValidation();

                if (isValid)
                {
                    string url = txtUrl.Text.ToString().TrimStart(' ').TrimEnd(' ');
                    string login = txtLogin.Text.ToString().TrimStart(' ').TrimEnd(' ');
                    string clientKey = txtSystemKey.Text.ToString().TrimStart(' ').TrimEnd(' ');
                    string psw = txtPassword.Text.ToString().TrimStart(' ').TrimEnd(' ');

                    RestfulWebServiceUserDAO userDAO = new RestfulWebServiceUserDAO();
                    userDAO.authenticateUser(login, psw, clientKey, url);
                   //navigate to another page  from here ??
                }
            }

在RestfulWebServiceUserDAO类authenticateUser()方法中存在

public async override void authenticateUser(string login, string password, string clientkey, string systemurl)
        {

            string url = systemurl + "/rest/user?login=" + login + "&password=" + password + "&clientkey=" + clientkey + "&languageId=" + 1;  

            string result = await GetMyData(url);
           //or shall I navigate from here?? this is not allowed :|
        }

GetmyData()方法在RestfulWebServiceUserDAO类中与我上面标记的相同。

2 个答案:

答案 0 :(得分:1)

尝试等待GetMyData

string result = await GetMyData(url)

答案 1 :(得分:1)

一旦你去异步,你需要一直异步到顶部。但是你需要总是返回一个等待的(通常是Task)。

事件处理程序和方法覆盖的异常。但在这种情况下,那些将是一场不容易的。

你的代码中有什么问题,尽管在你的authenticateUser(按惯例,应该称为AuthenticateUserAsync)方法中,你正在等待GetMyData的结果(同样,{{1} }),您没有向调用者返回任何等待结果。 Becaus aysnc方法在遇到第一个GetMyDataAsync语句后立即返回给调用者。

正因为如此,当await调用ApplicationBarDone_Click时,它会立即返回,因为它不是等待的。

如果您无法更改userDAO.authenticateUser,则无法使用authenticateUser。但作为Windows Phone,网络调用需要是异步的,您需要更改它。这样,你的async-await方法(记住约定?)应该是这样的:

AuthenticateUserAsync

你的public async override Task<string> AuthenticateUserAsync(string login, string password, string clientkey, string systemurl) { string url = systemurl + "/rest/user?login=" + login + "&password=" + password + "&clientkey=" + clientkey + "&languageId=" + 1; return await GetMyDataAsync(url); } 应该是这样的:

ApplicationBarDone_Click

要详细了解private async void ApplicationBarDone_Click(object sender, EventArgs e) { bool isValid = checkForValidation(); if (isValid) { string url = txtUrl.Text.ToString().TrimStart(' ').TrimEnd(' '); string login = txtLogin.Text.ToString().TrimStart(' ').TrimEnd(' '); string clientKey = txtSystemKey.Text.ToString().TrimStart(' ').TrimEnd(' '); string psw = txtPassword.Text.ToString().TrimStart(' ').TrimEnd(' '); RestfulWebServiceUserDAO userDAO = new RestfulWebServiceUserDAO(); string result = await userDAO.AuthenticateUserAsync(login, psw, clientKey, url); // do whatever you need to do after login. // just remember that, during the call to userDAO.AuthenticateUserAsync // the UI is responsive and the user can click again } } 编程,请阅读my curation