此篇博文基于《silverlight4数据与通信之WebClient详解 silverlight4版》,查看请请点击这里
这里用上一篇文章用过的示例,只不过稍微做一点小的改动,使用 WebRequest 提交书籍编号数据,并根据书籍号返回价格信息。
< TextBlock x:Name ="lblPrice" Text ="价格:" Foreground ="White"
HorizontalAlignment ="Left" VerticalAlignment ="Center"
Margin ="20 0 0 0" ></ TextBlock >
</ Border >
</ Grid > < Grid.RowDefinitions >
< RowDefinition Height ="40" ></ RowDefinition >
< RowDefinition Height ="*" ></ RowDefinition >
< RowDefinition Height ="40" ></ RowDefinition >
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition ></ ColumnDefinition >
</ Grid.ColumnDefinitions >
< Border Grid.Row ="0" Grid.Column ="0" CornerRadius ="15"
Width ="240" Height ="36"
Margin ="20 0 0 0" HorizontalAlignment ="Left" >
< TextBlock Text ="书籍列表" Foreground ="White"
HorizontalAlignment ="Left" VerticalAlignment ="Center"
Margin ="20 0 0 0" ></ TextBlock >
</ Border >
< ListBox x:Name ="Books" Grid.Row ="1" Margin ="40 10 10 10"
SelectionChanged ="Books_SelectionChanged" >
< ListBox.ItemTemplate >
< DataTemplate >
< StackPanel >
< TextBlock Text =" {Binding Name} " Height ="32" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ListBox.ItemTemplate >
</ ListBox >
< Border Grid.Row ="2" Grid.Column ="0" CornerRadius ="15"
Width ="240" Height ="36" Background ="Orange"
Margin ="20 0 0 0" HorizontalAlignment ="Left" > < Grid Background ="#46461F" >
编写 HttpHandler,注意我使用了 context.Request.Form["No"],在后面我们将使用 WebRequest
在 RequestReady 方法中将数据写入请求流:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace sample.Web
{
/// <summary>
/// BookHandler2 的摘要说明
/// </summary>
public class BookHandler2 : IHttpHandler
{
public static readonly string [] PriceList = new string [] {
" 66.00 " ,
" 78.30 " ,
" 56.50 " ,
" 28.80 " ,
" 77.00 "
};
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = " text/plain " ;
context.Response.Write(PriceList[Int32.Parse(context.Request.Form[ " No " ])]);
}
public bool IsReusable
{
get
{
return false ;
}
}
}
}
在界面加载时绑定书籍列表
private void UserControl_Loaded( object sender, RoutedEventArgs e)
{
List < BookClass > books = new List < BookClass > ()
{
new BookClass( " Professional ASP.NET 3.5 " ),
new BookClass( " ASP.NET AJAX In Action " ),
new BookClass( " Silverlight In Action " ),
new BookClass( " ASP.NET 3.5 Unleashed " ),
new BookClass( " Introducing Microsoft ASP.NET AJAX " )
};
Books.ItemsSource = books;
}
接下来在 SelectionChanged 事件中实现用户选择书籍时,我们使用 WebRequest 提交书籍编号,并且
获得价格数据,仍然采用异步模式,提供 RequestReady和 ResponseReady 两个回调函数:
private string bookNo;
private void Books_SelectionChanged( object sender, SelectionChangedEventArgs e)
{
bookNo = Books.SelectedIndex.ToString();
// 端口可根据自己的情况随便更改
Uri endpoint = new Uri(String.Format( " http://localhost:80/BookHandler2.ashx " ));
WebRequest request = WebRequest.Create(endpoint);
request.Method = " POST " ;
request.ContentType = " application/x-www-form-urlencoded " ;
request.BeginGetRequestStream( new AsyncCallback(RequestReady), request);
// request.BeginGetResponse(new AsyncCallback(ResponseReady), request);
}
实现 RequestReady 方法,将书籍的编号写入请求流中。要注意添加System.IO命名空间。
void RequestReady(IAsyncResult asyncResult)
{
WebRequest request = asyncResult.AsyncState as WebRequest;
Stream requestStream = request.EndGetRequestStream(asyncResult);
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(String.Format( " No={0} " , bookNo));
writer.Flush();
}
request.BeginGetResponse( new AsyncCallback(ResponseReady), request);
}
实现 ResponseReady 方法,显示返回的结果。
void ResponseReady(IAsyncResult asyncResult)
{
WebRequest request = asyncResult.AsyncState as WebRequest;
WebResponse response = request.EndGetResponse(asyncResult);
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream);
// lblPrice.Text = "价格:" + reader.ReadToEnd();
// lblPrice.Dispatcher.BeginInvoke(new UpdatePriceDelegate(UpdatePrice), reader.ReadToEnd());
// ‘charleslau’的方法,可以运行
string price = reader.ReadToEnd();
if ( this .lblPrice.CheckAccess())
{
this .lblPrice.Text = " 价格: " + price;
}
else
{
this .Dispatcher.BeginInvoke( new UIContextChangedEventHandler(UIContextChanged), price);
}
}
}
public delegate void UIContextChangedEventHandler( object state);
private void UIContextChanged( object state)
{
this .lblPrice.Text = " 价格: " + (String)state;
}
至此,大功告成,可以访问了,效果参见上一篇博文,文中有很多注释的地方,那是我参考的实例是silverlight2beta版测试通过的,在silverlight4中有些许不同,我已经做了修改,代码测试可以通过。下面附加后台完整代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
namespace sample
{
public partial class s13 : UserControl
{
public s13()
{
InitializeComponent();
}
private void UserControl_Loaded( object sender, RoutedEventArgs e)
{
List < BookClass > books = new List < BookClass > ()
{
new BookClass( " Professional ASP.NET 3.5 " ),
new BookClass( " ASP.NET AJAX In Action " ),
new BookClass( " Silverlight In Action " ),
new BookClass( " ASP.NET 3.5 Unleashed " ),
new BookClass( " Introducing Microsoft ASP.NET AJAX " )
};
Books.ItemsSource = books;
}
private string bookNo;
private void Books_SelectionChanged( object sender, SelectionChangedEventArgs e)
{
bookNo = Books.SelectedIndex.ToString();
// 端口可根据自己的情况随便更改
Uri endpoint = new Uri(String.Format( " http://localhost:80/BookHandler2.ashx " ));
WebRequest request = WebRequest.Create(endpoint);
request.Method = " POST " ;
request.ContentType = " application/x-www-form-urlencoded " ;
request.BeginGetRequestStream( new AsyncCallback(RequestReady), request);
// request.BeginGetResponse(new AsyncCallback(ResponseReady), request);
}
void RequestReady(IAsyncResult asyncResult)
{
WebRequest request = asyncResult.AsyncState as WebRequest;
Stream requestStream = request.EndGetRequestStream(asyncResult);
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(String.Format( " No={0} " , bookNo));
writer.Flush();
}
request.BeginGetResponse( new AsyncCallback(ResponseReady), request);
}
void ResponseReady(IAsyncResult asyncResult)
{
WebRequest request = asyncResult.AsyncState as WebRequest;
WebResponse response = request.EndGetResponse(asyncResult);
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream);
// lblPrice.Text = "价格:" + reader.ReadToEnd();
// lblPrice.Dispatcher.BeginInvoke(new UpdatePriceDelegate(UpdatePrice), reader.ReadToEnd());
// ‘charleslau’的方法,可以运行
string price = reader.ReadToEnd();
if ( this .lblPrice.CheckAccess())
{
this .lblPrice.Text = " 价格: " + price;
}
else
{
this .Dispatcher.BeginInvoke( new UIContextChangedEventHandler(UIContextChanged), price);
}
}
}
public delegate void UIContextChangedEventHandler( object state);
private void UIContextChanged( object state)
{
this .lblPrice.Text = " 价格: " + (String)state;
}
// private void UpdatePrice(string price)
// {
// lblPrice.Text = "price:" + price;
// }
// private delegate void UpdatePriceDelegate(string price);
}
}
感谢李老师和回帖的前辈,我对数据通信知之甚少,如有纰漏,敬请指出