代码改变世界

Silverlight轻量级取数方案(带源码)

2009-12-06 01:02  Amar-Yao  阅读(2538)  评论(7编辑  收藏  举报

  最近一直在做Flash交互相关的东西。主要思想就是在Flash声明的<param>中放入取数的URL,Flash控件中自己去请求这个URL。然后我们C#代码只需在这个URL指定的页面Response.Write拼好的数据XML字符串就行了。

  其实这样干净利索的取数方案一样也适合在Silverlight中使用。这种方法可以避开使用笨重的WCF服务,但其能够处理的问题范围较窄所以我把它称为Silverlight的轻量级取数方案。

  那么下面我们就来详细说说这种取数方法。

  首先我们要在使用到这个Silverlight控件的页面中加入取数的URL,这个URL往往都是动态的(根据部署环境的不同URL不同)。所以我们要在aspx.cs里处理这个URL,用<%=%>输出到aspx前端。

<param name="InitParams" value="<%= DataUrl %>" />

 

  需要注意的是InitParams和其后面的value形式(key=value)都是固定的。不熟悉的请参阅SL相关文档。后台代码很简单。DataUrl其实就是这个aspx页面的一个属性。

 

代码
        public string DataUrl
        {
            
get
            {
                
return GetUrl();
            }
        }

        
protected void Page_Load(object sender, EventArgs e)
        {

        }

        
private string GetUrl()
        {
            
string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri;
            url 
= url.Replace("Default.aspx""Data/output.aspx");
            url 
= string.Format("data={0}", url);
            
return url;
        }

 

   上面代码中我们可以看出,我的用来输出数据的页面其实就是Data目录下的output.aspx。

   这里的代码就要根据业务逻辑不同,也就是说数据不同来构造你的数据xml了。作为示例我只是简单的输出了一段xml。

代码
    public partial class output : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
string data = "<Data><Person>yza1</Person><Person>yza2</Person></Data>";
            Response.ContentType 
= "text/xml";
            Response.Clear();
            Response.Write(data);
        }
    }

 

   那么下面最关键的就是我们在Silverlight中怎么请求这个页面并获得数据呢?这里HttpWebResponse,HttpWebRequest类可以帮助我们。

 首先在你的App启动时要把InitParams中的Url取出来放到App的实例变量中。

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            DataUrl 
= e.InitParams["data"];
            
this.RootVisual = new MainPage();
        }

 

   下面是具体的请求和接受数据的代码。

代码
public MainPage()
        {
            InitializeComponent();

            
string url = ((App)Application.Current).DataUrl;
            HttpWebRequest request 
= (HttpWebRequest)HttpWebRequest.Create(url);

            request.BeginGetResponse(
new AsyncCallback(RequestReady), request);
        }

        
public void RequestReady(IAsyncResult result)
        {
            HttpWebRequest request 
= (HttpWebRequest)result.AsyncState;
            HttpWebResponse response 
=(HttpWebResponse)request.EndGetResponse(result);
            Stream stream 
= response.GetResponseStream();
            
using (StreamReader sr = new StreamReader(stream))
            {
                
string str = sr.ReadToEnd();
                txt.Dispatcher.BeginInvoke(() 
=> { txt.Text = str; });
            }
        }

 

   我们用到HttpWebRequest和HttpWebResponse异步的请求和接受数据。并把收到的xml字符串装进TextBox里。Demo就这么简单。

   但如果我们往深了想一想,这种取数据的方式避免了WCF中的很多麻烦,可以称得上干净利索。同时这种方法要想发挥最大作用就要配合SilverlightDataSet使用了(关于SilverlightDataSet请见我前面的那片Silverlight传递DataTable终极解决方案的Blog)。要说缺点嘛估计也有,就是如果传递实体类你得自己处理序列化和反序列化得问题,还有就是传递的xml很大时要进行压缩或分段。

   这种方式作为aspx中嵌入的数据量较小的SL控件的取数方法还是很不错的。不是吗?

   源代码下载