SilverLight學習筆記--Silverlight中WebRequest通訊

     本文我們學習如何使用WebRequest類實現客戶端和服務器端的通訊。
     本例處理過程:在客戶端,我們在文本框中輸入任意文本,然後用POST方法向服務器端傳遞信息,服務器端收到從客戶端傳來的信息後做相應處理,再向客戶端返回服務器端的信息,客戶端收到服務器端信息後也做相應處理然後在客戶端界面上顯示處理結果。效果如下:

                        
新建 Silverlight應用程序,命名爲:SLWebRequestTest,在SLWebRequestTest.Web項目下,建立一個Handler,命名爲:WebRequestHandler.ashx,它負責處理響應客戶端請求並返回處理結果。
如下圖:


                        

1、建立程序界面
Page.xaml代碼如下:

<UserControl x:Class="SLWebRequestTest.Page"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
 
    Width
="400" Height="300">

    
<StackPanel Width="400" Height="250" Background="Wheat" >
        
<TextBlock Text="請輸入傳遞到服務器的數據" TextAlignment="Center" Foreground="Red" Margin="2" FontSize="16"></TextBlock>
        
<TextBox  x:Name="tbClientContent" Width="250"></TextBox>
        
<Button  x:Name="btnGetData" Width ="200" Height="25" Content="獲取數據"  Click="btnGetData_Click" Margin="20"></Button>
        
<TextBlock Text="通過WebRequest從服務器取得的數據如下" TextAlignment="Center" Foreground="Red" Margin="2" FontSize="16"></TextBlock>
        
<TextBlock x:Name="tbRetText" Text="當前內容爲空" TextAlignment="Center" Foreground="Green" FontSize="16"></TextBlock>

    
</StackPanel>
</UserControl>

2、客戶端完成的工作
i、向服務器端POST客戶端信息
ii、向服務器端發起異步請求
iii、接收服務器端返回的數據,做相應處理後顯示在界面上。

Page.xaml.cs全部代碼如下:


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;
using
 System.Threading;

namespace
 SLWebRequestTest
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class
 Page : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
string
 clientInfoStr;
        
string serverInfoStr = "當前無信息"
;
        
private
 SynchronizationContext currentContext;  

        
public
 Page()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InitializeComponent();
            
this.currentContext =
 SynchronizationContext.Current;   
        }


        
private void btnGetData_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//設置Uri地址

            Uri endpoint = new Uri("http://localhost:54292/WebRequestHandler.ashx");

            
//獲取POST到Server端的數據

            clientInfoStr = this.tbClientContent.Text.ToString();

            
//
首先對代表Web請求的對象進行實例化。但在此並不是使用構造函數來實例化對象,而是調用靜態的WebRequest.Create()方法,
            
//
WebRequest類是支持不同網絡協議的類層次結構的一部分,爲了給請求類型接收一個對正確對象的引用,需要一個工廠(factory)機制。WebRequest.Create()方法會爲給定的協議創建合適的對象。
            
//WebRequest類代表要給某個URI發送信息的請求,URI作爲參數傳送給Create()方法。WebResponse類代表從服務器獲取的數據。


            WebRequest request 
= WebRequest.Create(endpoint);  
            request.Method 
= "POST"
;
            request.ContentType 
= "application/x-www-form-urlencoded"
;

ContractedSubBlock.gifExpandedSubBlockStart.gif            
向服務器端POST信息
#region 向服務器端POST信息
            clientInfoStr 
= this.tbClientContent.Text.ToString();  //取得將要POST的信息
            request.BeginGetRequestStream(new AsyncCallback(RequestCallBack), request);
            
#endregion



            
//說明:有的在此處把
            
//
 request.BeginGetRequestStream(new AsyncCallback(RequestReady), request);
            
//
 request.BeginGetResponse(new AsyncCallback(ResponseReady), request);
            
//寫在一起,這樣是沒用的。 因爲是在兩個線程裏處理的, 一開始請求就接收返回值了,所以必須把BeginGetResponse放到BeginGetRequestStream的回調函數中執行


        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
POST信息到服務器端#region POST信息到服務器端
        
private  void RequestCallBack(IAsyncResult asynchronousResult)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            WebRequest request 
=
 (WebRequest)asynchronousResult.AsyncState;
   
            Stream postStream 
=
 request.EndGetRequestStream(asynchronousResult);

            
string postData = String.Format(" ClientInfo = {0}"
, clientInfoStr);

            
try

ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
using (StreamWriter writer = new
 StreamWriter(postStream))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    writer.Write(postData);
                    writer.Flush();
                }


            }

            
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
string ke =
 ex.ToString();
            }


ContractedSubBlock.gifExpandedSubBlockStart.gif            
向服務器端請求返回信息#region 向服務器端請求返回信息
            
//WebRequest類的一個特性就是可以異步請求頁面。由於在給主機發送請求到接收響應之間有很長的延遲,因此,異步請求頁面就顯得比較重要。
            
//
像WebClient.DownloadData()和WebRequest.GetResponse()等方法,在響應沒有從服務器回來之前,是不會返回的。
            
//
如果不希望在那段時間中應用程序處於等待狀態,可以使用BeginGetResponse() 方法和 EndGetResponse()方法,
            
//
BeginGetResponse()方法可以異步工作,並立即返回。在底層,運行庫會異步管理一個後臺線程,從服務器上接收響應。
            
//BeginGetResponse() 方法不返回WebResponse對象,而是返回一個執行IAsyncResult接口的對象。使用這個接口可以選擇或等待可用的響應,然後調用EndGetResponse()蒐集結果。

            request.BeginGetResponse(new AsyncCallback(OnResponse), request);
            
#endregion




        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
接收服務器端的信息#region  接收服務器端的信息
        
protected void OnResponse(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

            WebRequest wrq 
=
 (WebRequest)ar.AsyncState;

            
//
對應 BeginGetResponse()方法,在此處調用EndGetResponse()蒐集結果。
            
//WebResponse類代表從服務器獲取的數據。調用EndGetResponse方法,實際上是把請求發送給Web服務器,創建一個Response對象。

            WebResponse wrs = wrq.EndGetResponse(ar);



            
// 讀取WebResponse對象中內含的從服務器端返回的結果數據流

            using (Stream responseStream = wrs.GetResponseStream())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                StreamReader reader 
= new
 StreamReader(responseStream);
                
string retGet =
 reader.ReadToEnd();
                serverInfoStr 
=
 retGet;

                
//
通過Thread完成對UI的修改
                
//因爲在多線程情況下,不能在背景線程裏操作UI線程, 改爲:

                Thread mythread = new Thread(new ThreadStart(AcrossThread));

                mythread.Start();
            }


        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
修改UI內容#region 修改UI內容

        
private void AcrossThread()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            currentContext.Post(result 
=>

ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.tbRetText.Text = serverInfoStr;  //在此處修改UI內容


            }
null);
        }

        
#endregion

        
#endregion



    }

}


3、服務器端完成的工作
在建立的Handler中接收客戶端的信息,做相應處理後返回給客戶端。
WebRequestHandler.ashx.cs全部代碼如下:

 

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;

namespace  SLWebRequestTest.Web
{
    
public   class  WebRequestHandler : IHttpHandler
    {

        
public   void  ProcessRequest(HttpContext context)
        {
            
// 讀取從客戶端傳來的參數
            
//  string clientInfoStr = context.Request.Params.Get("ClientInfo");  
            
// string clientInfoStr = context.Request.Form["ClientInfo"]; 
             string  clientInfoStr  =  context.Request.Form[ 0 ];

            
// 返回信息
            context.Response.ContentType  =   " text/plain " ;
            context.Response.Write(
" Server Received Client Info: "   +  clientInfoStr  +   " \n Server Return To Client: Welcome To Server " );
        }

        
public   bool  IsReusable
        {
            
get
            {
                
return   false ;
            }
        }
    }
}



 


前往:Silverlight學習筆記清單
 

本文程序在Silverlight2.0和VS2008環境中調試通過。本文參照了部分網絡資料,希望能夠拋磚引玉,大家共同學習。
(轉載本文請註明出處)

轉載於:https://www.cnblogs.com/wsdj-ITtech/archive/2009/08/27/1554952.html