本篇用一个示例(简单的域名查询)介绍 WebRequest 类和 WebResponse 类及如何实现无策略文件实现跨域访问。
无策跨域略文件实现跨域访问
上一篇介绍的的跨域访问使用策略文件实现的,如果不是自己的网站或无法加策略文件的网站将无法用Silverlight访问了。另一种思路是用像在Ajax中,设置DomainName属性欺骗浏览器(仅IE)、Javascript的Src属性、iframe等实现,然后在把数据传给SL,这些实现都不太理想,要么浏览器兼容不好,要么需用服务器程序设置输出Javascript等。这里用的方式是用Silverlight调用本域服务器的程序,服务器程序调用外的资源然后返回到Silverlight中,这种代理的方式效果较为理想,缺点是占用服务器资源。
WebRequest/WebResponse
这两个类相对于上一篇介绍的WebClient更底层,实现的功能更多,可以设置ContentType、跟服务器POST、GET数据,但相对与.NET FX的WebRequest/WebResponse功能还差一些,目前该类也只支持异步调用、跨域访问需策略文件等。详细功能请查阅MSDN。
示例(简单域名查询):
域名合法性检查、错误处理,优雅的显示查询结果从略。
具体见介绍域名查询的文章:《ASP.NET(c#)实现中英文域名查询》。
这里只能查询英文域名,中文域名查询会出现乱码,原因是万网的编码格式为GB2312,而Silverlight的编码格式为UTF8,若要实现中文域名查询,必须转换编码格式(见另一篇文章:《转换文本编码方式》)。
XAML:
<Canvas Background="DarkGreen">
<TextBlock Foreground="Yellow" Canvas.Left="20"
Canvas.Top="30">请输入域名:</TextBlock>
<TextBox x:Name="txtDomainName" Canvas.Left="110"
Canvas.Top="30" Width="90" Height="22">
</TextBox>
<TextBox x:Name="txtType" GotFocus="txtType_GotFocus"
LostFocus="txtType_LostFocus" IsReadOnly="True" Cursor="Arrow"
Width="80" Height="22" Canvas.Left="210" Canvas.Top="30">
<TextBox.Background>
<!--显示CombBox的背景图片,模拟CombBox-->
<ImageBrush ImageSource="1.png"
AlignmentX="Right" AlignmentY="Center">
</ImageBrush>
</TextBox.Background>
</TextBox>
<ListBox x:Name="lstType" Width="80" SelectionChanged="lstType_SelectionChanged"
Canvas.Left="210" Canvas.Top="52" MaxHeight="100" Visibility="Collapsed">
<ListBoxItem Content=".com"></ListBoxItem>
<ListBoxItem Content=".cn"></ListBoxItem>
<ListBoxItem Content=".net"></ListBoxItem>
<ListBoxItem Content=".com.cn"></ListBoxItem>
<ListBoxItem Content=".org"></ListBoxItem>
<ListBoxItem Content=".gov"></ListBoxItem>
</ListBox>
<Button x:Name="btnSearch" Content="查询"
Canvas.Left="300" Canvas.Top="30"
Width="60" Height="22" Click="Button_Click">
</Button>
</Canvas>
C#:
private void Button_Click(object sender, RoutedEventArgs e)
{
string uri = HttpUtility.UrlEncode(
"http://panda.www.net.cn/cgi-bin/check.cgi?area_domain=" +
txtDomainName.Text + txtType.Text);
WebRequest webRequest = WebRequest.Create(
new Uri("http://localhost:2053/DomainName_Web/getxml.aspx?url=" +
uri, UriKind.Absolute));
webRequest.BeginGetResponse(new AsyncCallback(ResponseCallBack), webRequest);
}
private void ResponseCallBack(IAsyncResult asyncResult)
{
WebRequest webRequest = asyncResult.AsyncState as WebRequest;
WebResponse webResponse = webRequest.EndGetResponse(asyncResult);
Stream responseStream = webResponse.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
string result = streamReader.ReadToEnd();
streamReader.Close();
HtmlPage.Window.Alert(result);
}
/// <summary>
/// 文本框获得焦点,显示ListBox来模拟CombBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtType_GotFocus(object sender, RoutedEventArgs e)
{
txtType.MouseLeftButtonDown += new MouseButtonEventHandler(txtType_MouseLeftButtonDown);
lstType.Visibility = Visibility.Visible;
}
/// <summary>
/// 文本框失去焦点,隐藏ListBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtType_LostFocus(object sender, RoutedEventArgs e)
{
txtType.MouseLeftButtonDown -= new MouseButtonEventHandler(txtType_MouseLeftButtonDown);
lstType.Visibility = Visibility.Collapsed;
}
/// <summary>
/// 选中ListBox的一项,显示在TextBox中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lstType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
txtType.Text = (lstType.SelectedItem as ListBoxItem).Content.ToString();
}
private void txtType_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
lstType.Visibility =
lstType.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
}
代理的实现代码:
Aspx:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Net" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
string url = Request["url"];
if (url != null)
{
WebClient webClient = new WebClient();
string result = webClient.DownloadString(Server.UrlDecode(url));
Response.Write(result);
}
}
</script>
在线演示:
结束语
下一篇介绍Silverlight调用 Web Service。