• 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调用的方法有点像呢?

    …………………………………………………………………………喜欢的话……………请推荐吧………………………………………………………

    估计再写一篇就完结了

    下一篇公布源码

  • 相关阅读:
    招标问什么
    其他房产
    长沙
    flume kafka
    http://www.zhihu.com/question/24301047
    38.NOW() 函数
    35.MID() 函数
    36.LEN() 函数
    34.UCASE() LCASE() 函数
    33.HAVING 子句
  • 原文地址:https://www.cnblogs.com/liulun/p/2336182.html
Copyright © 2020-2023  润新知