• WPF,Silverlight与XAML读书笔记第四十八


    说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

    这一部分我们重点讨论下Silverlight的网络与通讯功能。2.0版起,Silverlight支持多种模式的网络访问,从最原始的Silverlight控件支持的JavaScript方法,到Silverlight Framework内置的通过C#操作的各种类,几乎可以实现任意你想实现的功能。下面我们逐一讨论这些方法:

    1. 通过Silverlight控件的JavaScript支持

      这种方式的最终目的无非是把通过JavaScript获取的网络数据赋给Silverlight中的元素,代码大致如下所示:

      1 var valFromNet;
      2 var SL = document.getElementById("silverlightPlugIn");
      3 SL.content.findName("txt").Text = valFromNet;
        而JavaScript获取数据的方法又分如下两种:
    1. 编写使用xmlHttpRequest组件的JavaScript以Ajax方式异步获取数据

      我们通过如下代码段看一下这种方式的实现:

       1 function getAsyncResult() {
       2     xmlHttp = new XMLHttpRequest();
       3     xmlHttp.open("GET", "http://localhost:36360/ServerTime.ashx", true);
       4     xmlHttp.onreadystatechange = handleAJAXCallback;
       5     xmlHttp.send(null);
       6 }
       7 
       8 function handleAJAXCallback() {
       9     if ((xmlHttp.readyState == 4) && (xmlHttp.status == 200)) {
      10         var SL = document.getElementById("silverlightPlugIn");
      11         SL.content.findName("txt").Text = xmlHttp.responseText;
      12     }
      13 }

      可见,在回调函数中将异步获取的结果设置给Silverlight的元素。这个例子中我们访问的是一个ASP.NET编写的HttpHandler,可以将其换成其它任何可得到数据的Url。值得一提的在回调函数中队XmlHttpRequest的状态进行了检测,4即表示请求完成。 

    1. 在Silverlight项目中添加ASP.NET Web服务的引用,并访问

      在Silverlight中添加了对包含标记了[System.Web.Script.Services.ScriptService]属性的服务(方法也需要被标记为[WebMethod])的引用后,并页面中使用ScriptManager控件引用服务时,会自动生成JavaScript代理,这正是我们需要的东西,我们通过它来访问服务。完成上面的操作后我们就可以使用如下的JavaScript代码访问Web Service来获取我们想要的数据。

      注意在生成的JavaScript代理中我们使用WebServiceName.WebMethod这样的对象名来访问服务。

       1 function onLoad()
       2 {
       3     Service.getTime(onSuccess, onFailed,"");
       4 }
       5 
       6 function onSuccess(result)
       7 {
       8     var sl = document.getElementById("silverlightPlugIn");
       9     sl.content.findName("txtShort").Text = result.strShortTime;
      10     sl.content.findName("txtLong").Text = result.strLongTime;
      11 }
      12 
      13 function onFailed(result)
      14 {
      15     alert(result);
      16 }

      此处得到的result这个对象 ,已经被序列化为JSON格式。

     

    1. Silverlight Framework中的WebClinet与WebRequest方法

      首先我们来了解下WebClient的功能,在使用.NET进行Silverlight编程时,WebClient提供了最简单易用的网络访问功能,这个类的两个方法DownloadStringAsync与OpenReadAsync分别用来获取字符串及获取其它类型的数据,这些方法也是异步方法对应的回调函数分别为DownloadStringCompleted和OpenReadCompleted。下面的代码使用DownloadStringAsync演示了WebClient的使用:

       1 public Page()
       2 {
       3     InitializeComponent();
       4     WebClient cl = new WebClient();
       5     Uri uri = new Uri("http://localhost:36360/Web/Time.ashx");
       6     
       7 cl.DownloadStringCompleted += new DownloadStringCompletedEventHandler(cl_DownloadStringCompleted);
       8     cl.DownloadStringAsync(uri);
       9 }
      10 
      11 void cl_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
      12 {
      13     txtTime.Text = e.Result;
      14 }

      注意,使用WebClient需要添加对System.Net命名空间的引用。WebClient中其它常用属性还包括IsBusy,当数据在传输过程中此值返回true。WebClient中CancelAync方法用来取消正在进行的异步传输,并且此时DownloadStringCompleted/OpenReadCompleted事件参数的Cancelled属性会被置为true。
      接下来要介绍的是WebRequest类,这个类用来实现标准HTTP请求,主要包括一些通过POST来访问的地址。这个类的使用与.NET Framework中的HttpWebRequest很相似,下面给出一段核心代码作为示例:

       1 private void b_Click(object sender, RoutedEventArgs e)
       2 {
       3     Uri uri = new Uri("http://localhost:22602/WebRequestTest_Web/SubmitForm.ashx");
       4     WebRequest rq = WebRequest.Create(uri);
       5     rq.Method = "POST";
       6     rq.ContentType = "application/x-www-form-urlencoded";
       7     rq.BeginGetRequestStream(new AsyncCallback(RequestReady), rq);
       8     rq.BeginGetResponse(new AsyncCallback(ResponseReady), rq);
       9 }
      10 void RequestReady(IAsyncResult aR)
      11 {
      12     WebRequest rq = aR.AsyncState as WebRequest;
      13     Stream rqStream = rq.EndGetRequestStream(aR);
      14     StreamWriter w = new StreamWriter(rqStream);
      15     w.Write("t1=" + t1.Text + "&");
      16     w.Write("t2=" + t2.Text + "&");
      17     w.Write("t3=" + t3.Text );
      18     w.Flush();
      19 }

      上面代码中在获取请求数据与获取响应数据时都是发起的异步请求,在获取响应数据完成时需要下面的回调函数处理完成事件:

       1 void ResponseReady(IAsyncResult aR)
       2 {
       3     WebRequest rq = aR.AsyncState as WebRequest;
       4     using(WebResponse rs = rq.EndGetResponse(aR))
       5     using (Stream rpStream = rs.GetResponseStream())
       6     {
       7         StreamReader rdr = new StreamReader(rpStream);
       8         string postStatus = rdr.ReadToEnd();
       9     }
      10 }
    1. 在Silverlight中使用WCF

      Silverlight Framework中System.ServiceModel中的类提供了Silverlight对WCF的支持。下面的小例子给出了演示,我们通过在Visual Studio中添加WCF的引用来生成一个代理,这大大减少了编码的复杂度。我们逐段代码分析这个例子:
      首先是一个DataContract,这是服务器端与客户端传输数据类型的一个契约:

       1 [DataContract]
       2 public class Person
       3 {
       4     public Person(string strName, string strAge)
       5     {
       6         Name = strName;
       7         Age = strAge;
       8     }
       9     [DataMember]
      10     public string Name { get; set; }
      11     [DataMember]
      12     public string Age { get; set; }
      13 }

      然后是服务代码,这其中包括服务契约与服务实现:

       1 [ServiceContract]
       2 public interface IPersonService
       3 {
       4     [OperationContract]
       5     Person[] getPeople();
       6 }
       7 
       8 public class PersonService : IPersonService
       9 {
      10     public Person[] getPeople()
      11     {
      12         Person[] people = 
      13         { 
      14             new Person("Derek Snyder","32"), 
      15             new Person("Yoshi Latimer","19"),
      16             new Person("Mark Steel","31")
      17         };
      18         return people;
      19     }
      20 }

      对于这个简单的示例我们使用basicHttpBinding,服务的config中ServiceModel这部分参考如下代码:

       1 <system.serviceModel>
       2     <behaviors>
       3         <serviceBehaviors>
       4             <behavior name="PersonServiceBehavior">
       5                 <serviceMetadata httpGetEnabled="true"/>
       6                 <serviceDebug includeExceptionDetailInFaults="false"/>
       7             </behavior>
       8         </serviceBehaviors>
       9     </behaviors>
      10     <services>
      11         <service behaviorConfiguration="PersonServiceBehavior" name="PersonService">
      12             <endpoint address="" binding="basicHttpBinding" contract="IPersonService">
      13                 <identity>
      14                     <dns value="localhost"/>
      15                 </identity>
      16             </endpoint>
      17             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      18         </service>
      19     </services>
      20 </system.serviceModel>

      以上就是服务部分重要的代码,在添加了WCF服务引用后我们就可以使用如下的代码在WCF中访问服务:

      1 public Page()
      2 {
      3     InitializeComponent();
      4     Binding binding = new BasicHttpBinding();
      5     EndpointAddress endPoint = new EndpointAddress("http://localhost:36360/WCFService/PersonService.svc");
      6     PSProxy.PersonServiceClient client = new PSProxy.PersonServiceClient(binding, endPoint);
      7     client.getPeopleCompleted += new EventHandler<PersonService.PSProxy.getPeopleCompletedEventArgs>(client_getPeopleCompleted);
      8     client.getPeopleAsync();
      9 }

      回调函数中我们把得到的对象绑定到ItemsControl的数据模板中:
      ItemControl的XAML:

       1 <ItemsControl x:Name="_item">
       2     <ItemsControl.ItemTemplate>
       3         <DataTemplate>
       4             <StackPanel Orientation="Vertical">
       5                 <StackPanel Orientation="Horizontal">
       6                     <TextBlock FontWeight="Bold" Text="{Binding Name}" />
       7                     <TextBlock Text=" : "></TextBlock>
       8                     <TextBlock FontWeight="Bold" Text="{Binding Age}" />
       9                 </StackPanel>
      10             </StackPanel>
      11         </DataTemplate>
      12     </ItemsControl.ItemTemplate>
      13 </ItemsControl>

      回调函数:

      1 void client_getPeopleCompleted(object sender, PersonService.PSProxy.getPeopleCompletedEventArgs e)
      2 {
      3     _item.ItemsSource = e.Result;
      4 }

      客户端的配置在添加引用时自动生成不再赘述。

    以上这些就是Silverlight中访问网络的主要方式。

    本文完

  • 相关阅读:
    常用正则表达式
    在过滤器中设置一个应用范围内的路径
    在过滤器中设置一个应用范围内的路径
    shell編程之遠程開啓多個機器的ElasticSearch
    shell之CMD的使用,是用` `還是" "?
    shell編程之自動化集群搭建並啓動
    shell編程之權限
    登录用户出现‘’-bash-4.2$‘’的问题解决
    locate: can not open `/var/lib/mlocate/mlocate.db': No such file or directory
    Spring之mvc應用(包含aop)
  • 原文地址:https://www.cnblogs.com/lsxqw2004/p/4632821.html
Copyright © 2020-2023  润新知