HttpClient类包含在System.Net.Http命名空间中,是向以URI标识的网络资源发送HTTP请求和接收HTTP响应的基类。在HTTP请求中使用该类可以向Web服务发送GET、POST等异步请求,并接收服务器返回的响应数据。
下面以一个应用程序为例,介绍如何使用HttpClient类向Web服务发送GET请求并接收响应数据。该应用使用HttpClient类从网络获得XML格式的数据并在应用界面上显示。
在Visual Studio 2012中新建一个Windows应用商店的空白应用程序项目,并命名为HttpClientBasic。由于应用需要使用网络,那么应该首先为应用开启访问网络的权限,双击打开项目的package.appxmanifest文件,选择其中的功能选项卡。可以看到默认勾选了选项卡中的“Internet(客户端)”选项;若没有,请勾选项卡中的“Internet(客户端)”选项,然后保存修改。设置结果如图14-1所示。
图14-1 启用网络访问功能
从上面的介绍可以知道,本示例不只是获得网络数据,还要把获得的数据显示出来,为了实现这些功能,向应用界面添加一个按钮和三个文本框,代码如下所示:
<Canvas>
<TextBlock Text="URI地址" FontSize="18" Height="20" Canvas.Left="18" Canvas.Top="10" RenderTransformOrigin="0.4,0.5" />
<!--添加输入地址的文本框-->
<TextBox x:Name="InputAddrdess" Text="http://api.douban.com/book/subject/1220562?apikey=0112912082b26b5d0337b36188174217" FontSize="18" Height="20" Width="500" Canvas.Left="104" Canvas.Top="6"/>
<!--添加获取按钮-->
<Button Content="获取" Click="Start_Click" Canvas.Left="609" FontSize="18"/>
<TextBlock Text="状态" FontSize="18" Height="20" Canvas.Left="18" Canvas.Top="43" RenderTransformOrigin="0.857,-1.25" />
<!--添加显示请求状态的文本框-->
<TextBox x:Name="StatusText" Text="空闲" FontSize="18" Height="Auto" TextWrapping="Wrap" Canvas.Left="104" Canvas.Top="43" Width="500" />
<TextBlock FontSize="18" Text="返回的XML数据" Canvas.Left="18" Canvas.Top="89"></TextBlock>
<!--添加显示响应数据的文本框-->
<TextBox x:Name="OutputView" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" AcceptsReturn="True" FontSize="16" Height="170" Grid.RowSpan="2" Width="500" Canvas.Left="104" Canvas.Top="116" />
</Canvas>
在上面的代码中,“获取”按钮用来发送HTTP请求,三个文本框中一个用于输入URI地址,一个显示HTTP响应的内容,另外一个显示HTTP请求的状态和错误信息。
布局好前台界面后,下面来介绍后台功能的实现,首先在MainPage.xaml.cs文件中定义一个HttpClient类型的对象httpClient,并在构造方法中初始化httpClient对象,以便在后续代码中使用,具体实现代码如下所示:
//定义全局变量
private HttpClient httpClient;
public MainPage()
{
this.InitializeComponent();
httpClient = new HttpClient();
//增加可接收响应的最大缓冲大小,防止在接收Web服务返回的响应时发生异常
httpClient.MaxResponseContentBufferSize = 512 * 1024;
//添加用户代理标头
httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
}
上面的代码设置了httpClient对象的MaxResponseContentBufferSize和DefaultRequestHeaders属性。MaxResponseContentBufferSize表示可接收响应的最大缓冲大小,默认值为64KB,为避免因为缓冲区太小造成不能正确接收HTTP响应,这里把MaxResponseContentBufferSize属性设置为512 * 1024表示512KB。
在默认情况下,HttpClient对象不会将用户代理标头随HTTP请求一起发送,但一些Web服务器要求从客户端发送的HTTP请求附带用户代理标头,如果没有标头,则返回错误。所以为了避免这样的情况发生,本应用使用httpClient对象的DefaultRequestHeaders属性为HTTP请求添加了客户端代理标头。
对httpClient对象进行了一些基本设置之后,下面将使用httpClient对象发送GET请求和接收服务器响应并将结果显示在前台界面上。本示例通过给“获取”按钮添加单击事件来实现这些功能,“获取”按钮事件处理方法的代码如下所示:
private async void Start_Click(object sender, RoutedEventArgs e)
{
if (String.IsNullOrEmpty(InputAddrdess.Text))
{
//如果URI为空,输出提示信息
StatusText.Text = "输入的URI为空";
}
else
{
try
{
string responseBodyAsText;
OutputView.Text = "";
StatusText.Text = "等待响应...";
//发送请求
HttpResponseMessage response = await httpClient.GetAsync(InputAddrdess.Text);
//确认请求是否成功
response.EnsureSuccessStatusCode();
//更新请求状态
StatusText.Text = response.StatusCode + " " + response.ReasonPhrase;
//把XML响应转换成字符串形式
responseBodyAsText = await response.Content.ReadAsStringAsync();
//用换行替换响应中的<br>
responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine);
//显示响应
OutputView.Text = responseBodyAsText;
}
catch (HttpRequestException hre)
{
//显示异常信息
StatusText.Text = "错误" + hre.ToString();
}
catch (Exception ex)
{
//显示异常信息
StatusText.Text = ex.ToString();
}
}
}
在上面的代码中,首先会检查输入的URI地址是否为空。如果为空会在StatusText文本框里面显示“输入的URI为空”;如果不为空则调用httpClient对象的异步方法GetAsync请求已输入的URI资源,GetAsync方法会返回HttpResponseMessage类型的对象response。
使用response对象的EnsureSuccessStatusCode方法用于确认请求是否成功,如果成功则更新StatusText中的请求状态。接下来使用response 对象的Content.ReadAsStringAsync异步方法将响应内容写入到responseBodyAsText变量中,最后把responseBodyAsText变量中的内容显示在OutputView文本框中。上面的代码使用了try-catch块捕获可能发生的异常,若在catch块中捕捉到了异常,将在StatusText文本框中输出异常信息。
运行程序,会发现URI地址文本框已经有默认内容了,如果想要使用其他URI地址可以自行输入。单击“获取”按钮,会向输入的URI地址发送GET请求并得到响应结果,界面显示效果如图14-2所示。
图14-2界面显示