zoukankan      html  css  js  c++  java
  • Flex4中使用WCF 小宝马的爸爸

    虽然flex跟.net交互的首选是FluorineFx,但是如果在某些特定情况下(比如服务端是现成的,不允许修改,或者服务端开发方不懂FluorineFx为何物),这时webService还是挺有用的。
    WebService完全可以用"以BasicHttpBinding方式运行的WCF"代替。经过我的实际测试:对于基本类型(比如int,string,datetime以及它们对应的arrry以list),flex调用时能正确识别并“翻译”成as3中对应的int,String,Date以及Array类型,而复杂类型(比如自己在c#中定义的实体类或DataTable),flex调用时会报错,这类复杂类型我建议在wcf中用序列化技术处理成String后再返回。
    考虑到xml格式序列化后的信息量比较大,我倾向于选择json这种轻量级的格式,而且在.net4.0中新增了System.Runtime.Serialization.Json;能处理大多数的复杂对象序列化(但是DataTable处理不了)
    为了方便起见,我把一些序列化/反序列化的操作封装了一下:
     
    01 using System;
    02 using System.IO;
    03 using System.Runtime.Serialization.Json;
    04 using System.Text;
    05 using System.Data;
    06   
    07 namespace Helper
    08 {
    09     public static class Utils
    10     {
    11         /// <summary>
    12         /// 将对象序列化成json字符串(注:obj的类定义中要加正确的可序列化标志)
    13         /// </summary>
    14         /// <param name="obj"></param>
    15         /// <returns></returns>
    16         public static string ToJsonString(object obj)
    17         {
    18             string result = string.Empty;
    19             DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(obj.GetType());
    20   
    21             using (MemoryStream ms = new MemoryStream())
    22             {
    23                 jsonSerializer.WriteObject(ms, obj);
    24                 result = Encoding.UTF8.GetString(ms.ToArray());
    25             }
    26   
    27             return result;
    28         }
    29   
    30         /// <summary>
    31         /// json字符串反序列为对象
    32         /// </summary>
    33         /// <param name="jsonString"></param>
    34         /// <param name="objType"></param>
    35         /// <returns></returns>
    36         public static Object ToJsonObject(string jsonString, Type objType)
    37         {
    38             Object result = null;
    39             DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(objType);
    40   
    41             using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
    42             {
    43                 result = jsonSerializer.ReadObject(ms);
    44             }
    45   
    46             return result;
    47         }
    48   
    49         /// <summary>
    50         /// 将DataTable序列化成json字符串
    51         /// </summary>
    52         /// <param name="dt"></param>
    53         /// <returns></returns>
    54         public static string ToJsonString(this DataTable dt)
    55         {
    56             
    57             StringBuilder JsonString = new StringBuilder();
    58             //Exception Handling        
    59             if (dt != null && dt.Rows.Count > 0)
    60             {
    61                 JsonString.Append("{ ");
    62                 JsonString.Append("\"Rows\":[ ");
    63                 for (int i = 0; i < dt.Rows.Count; i++)
    64                 {
    65                     JsonString.Append("{ ");
    66                     for (int j = 0; j < dt.Columns.Count; j++)
    67                     {
    68                         if (j < dt.Columns.Count - 1)
    69                         {
    70                             JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString().Replace("\"", "\\\"") + "\":" + "\"" + dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\",");
    71                         }
    72                         else if (j == dt.Columns.Count - 1)
    73                         {
    74                             JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString().Replace("\"", "\\\"") + "\":" + "\"" + dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\"");
    75                         }
    76                     }
    77                     /**/
    78                     /*end Of String*/
    79                     if (i == dt.Rows.Count - 1)
    80                     {
    81                         JsonString.Append("} ");
    82                     }
    83                     else
    84                     {
    85                         JsonString.Append("}, ");
    86                     }
    87                 }
    88                 JsonString.Append("]}");
    89                 return JsonString.ToString();
    90             }
    91             else
    92             {
    93                 return null;
    94             }
    95         }
    96     }
    97 }
    不过,在开始正文之前,先提醒一下System.Runtime.Serialization.Json在序列化中要注意的问题:
    比如有一个类Person,定义如下:
     
    01 [Serializable]
    02 public class Person 
    03 {
    04     private string _name;
    05     private int _age;
    06     private float _salary;
    07  
    08     public string Name { set { _name = value; } get { return _name; } }        
    09     public int Age { set { _age = value; } get { return _age; } }        
    10     public float Salary { set { _salary = value; } get { return _salary; } }
    11       
    12 }
    对象
     
    Person p = new Person(){Age=30, Name="jimmy.yang", Salary=5000};
    序列后的字符串为
    {"_age":30,"_name":"jimmy.yang","_salary":5000}

    注意:这里并不是我所期待的{"Age":30,"Name":"jimmy.yang","Salary":5000},其实出现这样的结果也可以理解,因为属性的set,get内部就是方法调用,因此最终序列化的只是私有字段。但是如果把[Serializable]标志去掉,确能得到正确的结果:{"Age":30,"Name":"jimmy.yang","Salary":5000} 不知道这个算不算是System.Runtime.Serialization.Json的一个bug.
     
    实际flex应用中,用于传输的实体类99%以上保存的只是一些常规的基元类型(即int,string,date之类),所以为了避免上面提到的问题,我建议:
    1、实体类定义中只使用基本类型,去掉[Serializable]
    2、或者直接把实例成员用类似public string Name;的方式暴露出来,不过估计大数多酷爱OO的同学们要吐血了.
    ok,切入正题吧:
    1、先创建一个asp.net项目,然后添加一个wcf service,文件命名为:Sample.svc,对应的后端代码文件Sample.svc.cs内容如下:
    2、创建flex项目,然后在Data/Services面板中,添加一个webSerivce的引用
    点击Next之后,出现下面的界面
    设置wcf所在的WSDL URI后,一路next,最终Data/WebServices面板会变成下面这样
    注意上图中右侧工具栏上的几个小按钮,自己去试试吧,会有意外发现哦
     
    同时flex会生成几个as类文件(类似于wcf中svcutil.exe在client端自动生成的cs文件)
     
    剩下的事情,就很容易了,在mxml中测试一番,代码如下:
    001 <?xml version="1.0" encoding="utf-8"?>
    002 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    003                xmlns:s="library://ns.adobe.com/flex/spark" 
    004                xmlns:mx="library://ns.adobe.com/flex/mx"  xmlns:sample="services.sample.*">
    005       
    006   
    007     <fx:Script>
    008         <![CDATA[
    009               
    010             import com.adobe.serialization.json.JSONDecoder;            
    011             import mx.controls.Alert;
    012             import mx.rpc.events.FaultEvent;
    013             import mx.rpc.events.ResultEvent;           
    014             import valueObjects.Person;
    015               
    016               
    017             private function dataTableTest():void
    018             {
    019                 DataTableTestResult.token = sample.DataTableTest();
    020                 DataTableTestResult.addEventListener(ResultEvent.RESULT,onDataTableTestResult);
    021                 DataTableTestResult.addEventListener(FaultEvent.FAULT,onDataTableTestFault);
    022             }
    023               
    024             private function onDataTableTestFault(e:FaultEvent):void
    025             {
    026                 Alert.show("dataTableTest调用失败,result="+ e);
    027                 trace("dataTableTest.Fault=",e);
    028             }
    029               
    030             private function onDataTableTestResult(e:ResultEvent):void
    031             {
    032                 this.txtDataTable.text = "dataTableTest调用成功,结果:" + e.result;
    033             }
    034               
    035               
    036             private function listObjectTest():void
    037             {
    038                 ListObjectTestResult.token = sample.ListObjectTest();
    039                 ListObjectTestResult.addEventListener(ResultEvent.RESULT,onListObjectTestResult);
    040                 ListObjectTestResult.addEventListener(FaultEvent.FAULT,onListObjectFault);
    041             }
    042               
    043             private function onListObjectTestResult(e:ResultEvent):void
    044             {
    045                 this.txtList.text = "listObjectTest调用成功,结果:" + e.result;
    046                 var jsonDecoder:JSONDecoder = new JSONDecoder(e.result.toString(),true);
    047                 var obj:Object = jsonDecoder.getValue();
    048                 //把结果转化为强类型的集合
    049                 var list:Vector.<Person> = new Vector.<Person>();
    050                 for(var i:int=0;i<obj.length;i++)
    051                 {
    052                     list[i] = new Person(obj[i].Name,obj[i].Age,obj[i].Salary);
    053                 }               
    054                 trace(list);                
    055             }
    056               
    057             private function onListObjectFault(e:FaultEvent):void
    058             {
    059                 Alert.show("listObjectTest调用失败,result="+ e);
    060                 trace("listObjectTest.Fault=",e);
    061             }           
    062               
    063             private function objectTest():void
    064             {
    065                 ObjectTestResult.token = sample.ObjectTest();
    066                 ObjectTestResult.addEventListener(ResultEvent.RESULT,onObjectTestResult);
    067                 ObjectTestResult.addEventListener(FaultEvent.FAULT,onObjectTestFault);
    068             }
    069               
    070             private function onObjectTestResult(e:ResultEvent):void
    071             {
    072                 this.txtObject.text = "objectTest调用成功,返回值:" + e.result;
    073                 var jsonDecoder:JSONDecoder = new JSONDecoder(e.result.toString(),true);
    074                 var obj:Object = jsonDecoder.getValue();
    075                 var p:Person = new Person(obj.Name,obj.Age,obj.Salary);                 
    076                 this.txtObject.text += "\n" + "p.Age=" + p.Age + ",p.Name=" + p.Name + ",p.Salary=" + p.Salary;
    077             }
    078               
    079             private function onObjectTestFault(e:FaultEvent):void
    080             {               
    081                 this.txtObject.text = "objectTest调用失败,原因="+ e;
    082             }           
    083               
    084             private function doClick():void
    085             {               
    086                 objectTest();               
    087                 listObjectTest();
    088                 dataTableTest();
    089             }   
    090               
    091         ]]>
    092     </fx:Script>
    093     <fx:Declarations>
    094         <s:CallResponder id="ArrayTestResult"/>
    095         <sample:Sample id="sample" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
    096         <s:CallResponder id="DataTableTestResult"/>
    097         <s:CallResponder id="ListObjectTestResult"/>      
    098         <s:CallResponder id="ObjectTestResult"/>  
    099     </fx:Declarations>
    100     <s:Panel right="10" left="10" bottom="10" top="10" title="WCF 调用实例">
    101         <s:layout>
    102             <s:BasicLayout/>
    103         </s:layout>
    104         <mx:VDividedBox left="10" bottom="40" right="10" top="0">
    105             <s:TextArea height="33%" width="100%" id="txtObject">
    106                   
    107             </s:TextArea>
    108             <s:TextArea height="33%" width="100%" id="txtList">
    109                   
    110             </s:TextArea>
    111             <s:TextArea height="33%" width="100%" id="txtDataTable">
    112                   
    113             </s:TextArea>
    114         </mx:VDividedBox>
    115         <s:Button label="Call Wcf" horizontalCenter="0" id="btnCall" click="doClick()"  bottom="10"/>
    116     </s:Panel>
    117 </s:Application>
     
     
    后记:在实际开发中发现flex ide环境对于wcf的wsdl解析要比asmx慢不止N倍,但是一旦解析完成,生成相应的as类后,在运行时二耆速度相同。
     
    注:此文摘自博客园,如有侵权,请速与本人联系,将最快速度删除。
  • 相关阅读:
    JAVA 正则表达式 (超详细)
    <select>改造成<s:select>实现表单的回显功能
    打开新界面
    list删除操作 java.util.ConcurrentModificationException
    C# 增加 删除 更新 方法
    C# 网页内容获取
    excel 处理方法
    C# 读取excel
    sql 导入excel 遇到问题
    DataSet
  • 原文地址:https://www.cnblogs.com/gisera/p/2079464.html
Copyright © 2011-2022 走看看