SilverLight企業應用框架設計【五】客戶端調用服務端(使用JSON傳遞數據,自己實現RESTful Web服務)


來個索引

SilverLight企業應用框架設計【四】實體層設計+為客戶端動態生成服務代理(自己實現RiaService)

SilverLight企業應用框架設計【三】服務端設計

SilverLight企業應用框架設計【二】框架畫面

SilverLight企業應用框架設計【一】整體說明

 

在上一節中講到的自動生成的服務代理類核心代碼,如下

        public event ServiceEventHandler Completed;
        public void GetAllMenu()
        {
            var si = new ServiceInvoker();
            si.Completed += new ServiceEventHandler(si_Completed);
            si.PrepareInvoke("MenuService", "GetAllMenu", typeof(List<MenuM>));
            si.InvokeService();
        }
        void si_Completed(object sender, ServiceEventArgs e)
        {
            Completed(sender, e);
        }

大家注意到我們是通過ServiceInvoker來調用服務的

實例化ServiceInvoker類之后就注冊了ServiceEventHandler事件

此事件是服務調用完成后觸發的事件(silverlight 原生的ria service也有一個completed事件)

該事件相關代碼如下

    public class ServiceEventArgs : EventArgs
    {
        //服務方法的返回值
        public object Result { get; set; }
    }
    public delegate void ServiceEventHandler(object sender, ServiceEventArgs e);

在si.PrepareInvoke把需要調用的服務類名,方法名,返回值類型(如果有參數,這里還會自動加入參數)

PrepareInvoke方法如下

        public void PrepareInvoke(string ClassName,string MethodName,Type ResultType,params object[] objs)
        {
            className = ClassName;
            methodName = MethodName;
            resultType = ResultType;
            MemoryStream ms = new MemoryStream();
            var sb = new StringBuilder();            
            for(int i=0;i<objs.Length;i++)
            {
                var jsonSerializer = new DataContractJsonSerializer(objs[i].GetType());
                jsonSerializer.WriteObject(ms, objs[i]);
                var objStr = Encoding.UTF8.GetString(ms.ToArray(), 0, (int)ms.Length);
                ms.Position = 0;
                sb.AppendFormat("p{0}=", i);
                sb.AppendFormat("{0}", objStr);
                sb.Append("&");
            }
            ms.Close();
            paramStr = sb.ToString();
        }

在此方法中主要是記錄下這些信息,

另外把服務需要傳入的參數序列化成JSON字符串

緊接着就調用InvokeService方法

代碼如下

        public void InvokeService()
        {
            Uri serviceUri = new Uri("http://localhost/RTMDemo.Host/RTMDemo.Host.WCF.MenuService");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUri);            
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            var requestResult = request.BeginGetRequestStream(new AsyncCallback(RequestReady), request);
            return;
        }

明眼人一看就明了了

其實就是使用HTTPWebRequest來調用服務(服務端我們托管了HttpHandler的請求

RequestReady事件如下:

        void RequestReady(IAsyncResult asyncResult)
        {
            HttpWebRequest request = asyncResult.AsyncState as HttpWebRequest;
            Stream stream = request.EndGetRequestStream(asyncResult);
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                StreamWriter writer = new StreamWriter(stream);
                writer.Write(paramStr);
                writer.Write("MethodKey=RTMDemo.Host.WCF.{0}.{1}&", className,methodName);
                writer.Flush();
                writer.Close();
                request.BeginGetResponse(new AsyncCallback(ResponseReady), request);
            });
        }

在此事件中我們把服務類名方法名和參數寫入了請求流

ResponseReady事件如下

        void ResponseReady(IAsyncResult asyncResult)
        {
            HttpWebRequest request = asyncResult.AsyncState as HttpWebRequest;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                Stream responseStream = response.GetResponseStream();
                if (resultType == null)
                {
                    Completed(this, null);
                    return;
                }
                try
                {
                    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(resultType);
                    result = jsonSerializer.ReadObject(responseStream);
                }
                catch
                {
                }
                var se = new ServiceEventArgs();
                se.Result = result;
                Completed(this, se);
            });
        }

這個事件把服務端返回的結果(JSON數據)反序列化成實體類型,並賦值給ServiceEventArgs

然后觸發了Completed事件

也就是觸發我們服務端代理類的si_Completed事件

至此,調用服務端的類就解釋完了

下面我們看看是怎么調用服務端的

        private void InitMenu()
        {
            var ms = new MenuService();
            ms.Completed += new ServiceEventHandler((o, re) =>
            {                
                var AllMenu = re.Result as List<MenuM>;
                Common.ViewUtility.AllMenu = AllMenu;
                InitTopMenu();
            });
            ms.GetAllMenu();
        }

看看是不是與ria service調用的方法有點像呢?

…………………………………………………………………………喜歡的話……………請推薦吧………………………………………………………

估計再寫一篇就完結了

下一篇公布源碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM