C# 在Xamarin表单中处理调用RESTful web服务的异步/任务

C# 在Xamarin表单中处理调用RESTful web服务的异步/任务,c#,asynchronous,xamarin.forms,async-await,task,C#,Asynchronous,Xamarin.forms,Async Await,Task,我必须在我的Xamarin表单应用程序中调用RESTful web服务。 我想添加一个活动指示器,以避免在运行web服务调用时发生用户操作;所以我认为我必须使用C#async/Task,对吗 我必须使用的web服务是现有的,然后我必须遵循前面的规范。在这种情况下,我必须执行由两个步骤组成的登录。在第一个示例中,我必须通过将用户凭据发布到由返回的url+固定部分组成的url,然后将用户凭据发布到一个固定url,从而获得的真实基本url 我做了一些尝试,我看到我想要存储web服务响应内容的字符串是空

我必须在我的Xamarin表单应用程序中调用RESTful web服务。 我想添加一个活动指示器,以避免在运行web服务调用时发生用户操作;所以我认为我必须使用C#async/Task,对吗

我必须使用的web服务是现有的,然后我必须遵循前面的规范。在这种情况下,我必须执行由两个步骤组成的登录。在第一个示例中,我必须通过将用户凭据发布到由返回的url+固定部分组成的url,然后将用户凭据发布到一个固定url,从而获得的真实基本url

我做了一些尝试,我看到我想要存储web服务响应内容的字符串是空的,因为即使web服务调用没有完成,代码也会继续运行,我不知道如何处理它

这是我的密码:

HttpClient client = new HttpClient();

public async Task<string> Post(string url, FormUrlEncodedContent parameters)
{
    using (var response = await client.PostAsync(url, parameters))
    {
        return await response.Content.ReadAsStringAsync();
    };        
} 

// Used to bind ActivityIndicator IsRunning property in XAML file
public string ShowActivityIndicator { get; set; }

public async void ButtonClickMethod()
{
    ShowActivityIndicator = true;

    await GetLink();
    var user = await GetLink();

    ShowActivityIndicator = false;

    App.Navigation.PushAsync(new HomePage(user));
}

public string BaseUrl { get; set; }
public string LoginUrl { get { return BaseUrl + Constants.LoginUrlPart; }

public async Task GetLink(FormUrlEncodedContent parameters)
{
    var json = await Post(Constants.LinkUrl, parameters);

    // json is empty becouse web service call hasn't yet finished
    var response = JsonConvert.DeserializeObject<Link>(json);

    BaseUrl = response.Link;
}

public async Task<User> Login(FormUrlEncodedContent parameters)
{
    var json = await Post(LoginUrl);

    // json is empty becouse web service call hasn't yet finished
    var response = JsonConvert.DeserializeObject<User>(json);

    return response;
}
HttpClient=newhttpclient();
公共异步任务Post(字符串url、FormUrlEncodedContent参数)
{
使用(var response=wait client.PostAsync(url,参数))
{
return wait response.Content.ReadAsStringAsync();
};        
} 
//用于绑定XAML文件中的ActivityIndicator IsRunning属性
公共字符串ShowActivityIndicator{get;set;}
公共异步void按钮ClickMethod()
{
ShowActivityIndicator=true;
等待GetLink();
var user=await GetLink();
ShowActivityIndicator=false;
App.Navigation.PushAsync(新主页(用户));
}
公共字符串BaseUrl{get;set;}
公共字符串LoginUrl{get{return BaseUrl+Constants.loginurlport;}
公共异步任务GetLink(FormUrlEncodedContent参数)
{
var json=wait Post(Constants.LinkUrl,参数);
//json为空,因为web服务调用尚未完成
var response=JsonConvert.DeserializeObject(json);
BaseUrl=response.Link;
}
公共异步任务登录(FormUrlEncodedContent参数)
{
var json=wait Post(LoginUrl);
//json为空,因为web服务调用尚未完成
var response=JsonConvert.DeserializeObject(json);
返回响应;
}

谢谢您的帮助。

这并不是您问题的答案,但为什么不使用类似的库来简化此操作呢?我记得我曾尝试过一些第三方库来使用此web服务(我想我也尝试过重新安装,但我不确定)返回的JSON不是预期的。唯一返回正确响应的是RestSharp,但它没有PCL版本。web服务是使用CodeIgniter框架在PHP中开发的,不知道我是否需要使用一些特殊的精明。关于web服务,我要做的另一件事是,我必须使用
FormUrlEncodedCContent
来传递参数,在我尝试使用
StringContent
之前,响应并不像预期的那样。我被你的代码弄糊涂了。你的第一次
登录
调用了
GetLink
两次,没有任何参数,而
GetLink
需要一个参数,而你的第二次
登录
从未被调用。你能修复这个问题吗e代码,这样它至少可以编译?@YiyiChen:如果注释指示的
json
是空的,那么web服务返回一个空字符串。此时web服务调用已经完成。这并不是你问题的答案,但为什么不使用类似的库来轻松地完成此操作呢?我记得我尝试过一些第三方库使用此web服务(我想我也尝试过重新安装,但我不确定)返回的JSON不是预期的。唯一返回正确响应的是RestSharp,但它没有PCL版本。web服务是使用CodeIgniter框架在PHP中开发的,不知道我是否需要使用一些特殊的精明。关于web服务,我要做的另一件事是,我必须使用
FormUrlEncodedCContent
来传递参数,在我尝试使用
StringContent
之前,响应并不像预期的那样。我被你的代码弄糊涂了。你的第一次
登录
调用了
GetLink
两次,没有任何参数,而
GetLink
需要一个参数,而你的第二次
登录
从未被调用。你能修复这个问题吗e代码,这样它至少可以编译?@YiyiChen:如果注释指示的
json
为空,则web服务返回一个空字符串。此时web服务调用已完成。