听棠.NET

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

公告

Flex与.NET进行Remoting数据交换时注意的三个问题。

Posted on 2009-11-05 11:55 听棠.NET 阅读(...) 评论(...) 编辑 收藏

环境:客户端 Flex Builder 4
        服务端 FluorineFx配置的.NET服务

       采用AMF3进行remoting交互

对象:Flex 客户端定义的实体

package VO
{
 [RemoteClass(alias="ServiceLibrary.UserInfo")]
 public class UserInfoVO
 {
  public function UserInfoVO():void
  {
  }
  
  public var Id:String;
  public var UserName:String;
  public var NickName:String;
  public var Password:String;
  public var HeadImage:String;
  public var Gender:Number=0;
  public var TrueName:String;
  public var Phone:String;
  public var Mobile:String;
  public var Email:String;
  public var Province:String;
  public var City:String;
  public var Logins:Number=0;
  public var Flag:Number=0;
  public var LastLoginDate:String;
 }
}

.NET服务器端的实体对触采用ADO.NET Entity Framework生成,在此不细说了。

经过反复的试验,发现有三个细节问题要注意:

1、对于数字类型的,一定要有默认值

    比如:public var Gender:Number=0; public var Logins:Number=0;public var Flag:Number=0;
    如果对于数字类型的,在传递前没有值,对象传递到服务端会出错。因此,要么在对象赋值时对于数字的都要赋值。要么最好在类里就把默认值赋上,避免出错的情况。

 

2、对于日期类型的字段,在客户端如果采用Date类型|
public var LastLoginDate:Date;

那么在赋值时用new Date()生成的时间,在传递到服务器端时是UTC时间,时差差了8个小时。
var userVo:UserInfoVO=new UserInfoVO();
    userVo.Id="1";
    userVo.UserName=this.account.text;
    userVo.Password=this.pwd.text;
    userVo.LastLoginDate=new Date();

 

为了解决上面的问题,我们可以把类型设为String型。如:
public var LastLoginDate:String;

然后传递时采用new Date().toLocaleString()

如下:

var userVo:UserInfoVO=new UserInfoVO();
    userVo.Id="1";
    userVo.UserName=this.account.text;
    userVo.Password=this.pwd.text;
    userVo.LastLoginDate=new Date().toLocaleString();

通过时间的toLocaleString()转换成字符串,传递到服务端,就没有时差问题了。

 

但是对于FLEX这种富客户端,还是非常不建议让“客户端”来生成时间,传递到服务端。“客户端”可以随意的修改时间,因此,会导致时间的不一致性。

因此,对于创建时间之类的,最好是由服务端进行生成。

3、主键属性必须赋值

我的例子中Id属性为主键,虽然在Flex客户端的UserInfoVO类是没有定义“主键”的概念,但是要清楚服务器端的主健是哪个,这样,在传递对象到服务端时,对于主键值一定要赋值。比如:

var userVo:UserInfoVO=new UserInfoVO();
    userVo.Id="1";

我的Id不是INT自增长型的,而是varchar类型,我是想采用GUID来作为主键。

当然了,虽然GUID主健存在很多性能问题,比如“不易辨认”“性能低下”,但GUID也同样有一个优点,那就是“数据库无关性”。

这个“数据库无关性”也就是意味着,主健值完全由“业务系统”来决定,对于“富客户端”的模式,也就是有很多业务逻辑,会推到“客户端”去处理,在“富客户端”的模式里,我们要强调的主题是“尽量减少与服务器的交互,尽量的提高性能,减少对服务端的依赖”。那么,我们试想一下,如果是自增长INT型,为了实现“事务”效果,就必须要“先与服务器交互获得生成的ID值”,然后绑到子表中作为外键。。。这样的交互有点多余。

另外,GUID还有一个优点(也可能是缺点)那就是“无法推测性”,通过这样的GUID,就算被客户知道了WEB接口方式,但也由于无法推测主键值,而无法“遍历爬取信息”,我想“富客户端”的一个隐患,那就是暴露着的服务端接口,自增长ID就会相当危险,一旦人家知道你GetUserById()的地址,那从1到100万,所有的信息都被取走。。。当然了,关于安全可以用方法来控制的,比如我比较推荐用时间戳了。在这里不展开了,话太多了:)太乱。