vs2010 学习Silverlight学习笔记(12):数据与通信之WebRequest

概要:

    这是学习TerryLee的Silverlight笔记-数据通信部分,关于webRequest的代码在Silverlight3有些变动。
若想学好Silverlight数据通信部分,要多看看关于web通信的相关知识,同时还有异步线程的知识。

 

WebRequest

  数据接口代码:
代码
public class BookHandler : 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";
//webclient调用语句
//context.Response.Write(PriceList[Int32.Parse(context.Request.QueryString["No"])]);
//webRequest调用语句
context.Response.Write(PriceList[Int32.Parse(context.Request.Form["No"])]);

}

public bool IsReusable
{
get
{
return false;
}
}

还有实体类:
public class Book
{
public Book(string name)
{
this.Name = name;
}

public string Name { get; set; }
}

 


还有MainPage.xaml:
代码
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Background="Green" Grid.Column="0"
Width
="300" Height="35" CornerRadius="15">
<TextBlock Text="图书目录:" Foreground="Wheat" HorizontalAlignment="Left"
Margin
="10" VerticalAlignment="Top"></TextBlock>
</Border>
<ListBox Grid.Row="1" Grid.Column="0" x:Name="Books" Background="Blue"
Margin
="40 10 10 10" SelectionChanged="Books_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="Book" Text="{Binding Name}" Height="32" Foreground="Wheat"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Grid.Row="2" Grid.Column="0" Background="Orange" CornerRadius="15" Width="300"
Height
="35">
<TextBlock x:Name="BookM" Foreground="Wheat" HorizontalAlignment="Left" Margin="10">
</TextBlock>
</Border>
</Grid>

 
主要的MainPage.xaml.cs,因为用到Stream所以要引入Using System.IO
代码
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private string bookNo;

private void Books_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
bookNo
= Books.SelectedIndex.ToString();

Uri endpoint
= new Uri("http://localhost:49955/BookHandler.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);

}

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
List
<Book> books = new List<Book>() {
new Book("Professional ASP.NET 3.5"),
new Book("ASP.NET AJAX In Action"),
new Book("Silverlight In Action"),
new Book("ASP.NET 3.5 Unleashed"),
new Book("Introducing Microsoft ASP.NET AJAX")
};

Books.ItemsSource
= books;

}
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);
//BookM.Text = "价格:" + reader.ReadToEnd();
BookM.Dispatcher.BeginInvoke(new UpdatePriceDelegate(UpdatePrice), reader.ReadToEnd());
}
}
private void UpdatePrice(string price)
{
BookM.Text
= "price:" + price;
}
private delegate void UpdatePriceDelegate(string price);
}

 

 

注 意的部分:

  
老师的代码是在Silverlight2调试的,所以在Silverligh3,4时出现错误很正常。
 多数会出现:“NO”值为空的情况

context.Response.Write(PriceList[Int32.Parse(context.Request.Form["No"])]);

这是因为:

request.BeginGetRequestStream(new AsyncCallback(RequestReady), request);
request.BeginGetResponse(new AsyncCallback(ResponseReady), request);

 


源码中的这两句是异步操作,正常情况下要第一句线程运行完了,再运行第二句。但在异步操作中仅仅这样是无法控制线程的运行
情况的。所以会出现取不到值的情况。
所以我们将

request.BeginGetResponse(new AsyncCallback(ResponseReady), request); 


 


放在RequestReady()语句后面。

BookM.Dispatcher.BeginInvoke(new UpdatePriceDelegate(UpdatePrice), reader.ReadToEnd());

是什么意思呢?有什么作用呢?


delegate是定义委托的关键字,具体的处理方法呢就是BookM.Text = "price:" + price;


那么Dispatcher.BeginInvoke是干什么的呢?


msdn关于此方法的定义:


public DispatcherOperation BeginInvoke(
    Delegate d,
    params Object[] args
)

·  d

·    类型:System..::.Delegate

·    对采用多个参数的方法的委托,该委托将被推送到 Dispatcher 事件队列中。

·  

·  args

·    类型:array<System..::.Object>[]()[]

·    作为指定方法的参数传递的对象数组。

返回值

·    类型:System.Windows.Threading..::.DispatcherOperation
   在调用 BeginInvoke 后立即返回的一个对象,表示已发布到 Dispatcher 队列的操作。

 

·  Dispatcher是提供用于管理线程工作项队列的服务。BeginInvoke用与 Dispatcher 关联的线程上的指定参数数组以异步方式执行指定委托。

·  代码这样就不会出现接口取不到值的情况了。

总结:


  这篇例子的思路和处理问题的思路很简单,但是用到了很多作为新手并不常用的东西。我们作为新手不要恐惧,多接触多查查慢慢就会熟练的。
总目录
上一篇:vs2010 学习Silverlight学习笔记(11):数据与通信之WebClient
下一篇:vs2010 学习Silverlight学习笔记(13):数据与通信之WCF
posted @ 2010-05-18 08:35  耀哥  阅读(1886)  评论(4编辑  收藏  举报