听棠.NET

用积极乐观的心态,面对压力
posts - 307, comments - 10808, trackbacks - 112, articles - 5
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

公告

Flex AS3与 ADO.NET Entity Framework 实体对象数据类型转换(转)

Posted on 2009-09-25 09:25 听棠.NET 阅读(...) 评论(...) 编辑 收藏

源文:http://www.riafan.com/article.asp?id=84
Fluorine的官方帮助是以AMF0和AMF3两个版本来讲解Flex AS3(以下简称AS3)与Fluorine .NET之间(以下简称.NET)的数据类型转换的,此处我们仅以AMF3版本来介绍。几种数据类型转换方式中最方便的应该是AS3自定义对象转换为.NET值对象。

一、 AS3转换成.NET(以ToNetType.mxml和ToNetType.cs为例)

1. 基本类型的数据

比如说我们用一个方法要向服务器端发送一个人的基本信息:比如姓名、年龄和婚姻状况,可以简单地把姓名、年龄和婚姻状况作为该方法的参数传递。参数的个数及前后位置要和.Net对应,参数一多,很容易出错。而且很多时候还需要用.Net再次转换。此类数据转换基本上是一一对应,和HTTP Service和Web Service差不多,体现不了Remoting Service技术的优势。请参看源文件中的sendArgs方法。

2. 数组类型

 同样是上述情形,如果改用数组为参数,方法会看起来简洁很多。不过仍然数组的元素的前后位置也必须与服务器端一致。AS3数组通过Fluorine转换为.NET的IList接口数据类型,详情请参看sendArray方法。

3. 关联数组类型

联数组其实就是Object对象,它可以让我们动态添加属性。参数变成了Object对象的属性,再将Object对象高级参数传递,再也不用担心AS3与.Net文件中方法的参数个数及顺序必须一致了。AS3关联数组通过Fluorine转换为.NET的Hashtable,请参看AssoArray方法。

4. VO数据类型

再通过Fluorine,我们可以将ActionScript 自定义对象(如Person.as)转换为.NET的值对象(VO)(如Person.cs),从而实现AS3与.NET的Mapping(映射)。如sendVO方法,这两个类的类名可以不一样,属性名和属性个数都可以不一样(为了好记,最好相同)。实现映射有以下两种方法:

(1) 在ActionScript 类中注册类的别名。使用RemoteClass(alias=".Net全限定类名");

(2) 在web.config 文件中添加classMappings节点。

<classMappings>
    <classMapping>
        <type>.Net全限定名</type>
        <customClass>AS3全限定类名</customClass>
    </classMapping>
</classMappings>

在某些情况下第一种方法失效,可以尝试第二种方法。很显然,用值对象向.NET传递数据是最方便的。

当然还有ByteArray数据类型也是很重要的,比如说常见的大头拍应用,传统的方法在服务器端进行二进制编码,很麻烦效率也很差。如果用Fluorine对AS3和.NET都直接使用ByteArray数据类型,那就方便高效多了。

==============================================================
通过以上的文章,我选择是FLEX与.NET两边强类型数据交换,只要在类定义上使用RemoteClass(alias=".Net全限定类名")测试通过。
值得高兴的是,.NET服务端我采用的ADO.NET Entity Framework 自动生成的实体定义。看来这样的的单对象传递方式是可行的。
1、服务器端:
比如:数据库有Department表,那么采用ADO.NET Entity Framework 自动生成实体类。要注意最终生成的实体类的“全限定名”比如:ServiceLibrary.Department
2、FLEX客户端:
然后在FLEX中建立一个AS类,类名建议采用“VO”结尾,这样有利于区分FLEX客户端对象与服务器端对象。比如:
package
{
 [RemoteClass(alias="ServiceLibrary.Department")]
 public class VO
 {
  public function DepartmentVO():void
  {
  }
  public var Id:Number;
  public var Name:String;
  public var ParentId:Number;
  public var Phone:String;
  public var Fax:String;
  public var Des:String;

 }
}

以上注意必须有[RemoteClass(alias="ServiceLibrary.Department")]而且alias必需有,服务端全限定名也不能错,要不然数据转换会失败。

3、FLEX客户端Remoting 传递:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" creationComplete="application1_creationCompleteHandler(event)"
 >
 <s:Button x="51" y="118" label="按钮" id="btn" click="btn_clickHandler(event)"/>
 <mx:Label x="55" y="64" text="标签" id="label"/>
 <s:Button x="171" y="121" label="按钮" id="GetDepartment" click="GetDepartment_clickHandler(event)"/>
 <mx:Label x="171" y="75" text="标签" id="lblName"/>
 <fx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   import flash.net.NetConnection;
   import flash.net.Responder;
   import flash.events.ErrorEvent;
 
   
   var nc:NetConnection

   protected function btn_clickHandler(event:MouseEvent):void
   {
    // TODO Auto-generated method stub
    var resp:Responder=new Responder(onSuccess,onFaild);
    nc.call("ServiceLibrary.Sample.Echo",resp,"dd");
    
   }


   protected function application1_creationCompleteHandler(event:FlexEvent):void
   {
    // TODO Auto-generated method stub
    nc=new NetConnection();
    nc.objectEncoding=ObjectEncoding.AMF3;
    var gatewayUrl:String ="http://localhost:2908/ServerWeb/Gateway.aspx";
    
    nc.addEventListener(NetStatusEvent.NET_STATUS,netStateHandle);
    nc.connect(gatewayUrl);
    
   }
   protected function netStateHandle(evt:NetStatusEvent):void
   {
    this.label.text=evt.info.toString();
   }
   protected function onSuccess(re:String):void{
    this.label.text=re;
   }

   protected function onFaild(re:String):void{
    this.label.text=re;
   }

   protected function GetDepartment_clickHandler(event:MouseEvent):void
   {
    // TODO Auto-generated method stub
    var resp:Responder=new Responder(onDeptSuccess,onDeptFaild);
    nc.call("ServiceLibrary.SystemFramework.DepartmentFacade.GetDepartmentById",resp,1);
   }
   protected function onDeptSuccess(re:Object):void{
    var dept:DepartmentVO=re as DepartmentVO;
    this.lblName.text=dept.Name;
   }
   protected function onDeptFaild(re:String):void{
    this.lblName.text=re;
   }

  ]]>
 </fx:Script>
</s:Application>