今天在网上看到有人在问关于C#编写BLL层的一些问题,所以想到一个多月前做的一个小测试,今天把它整理一下,说一下思路,发出来大家交流一下.
首先,开头先讲一下多层结构,具体内容我就不会花太多篇幅,因为这方面的经验,我想搞.net BS的人比我更清楚.我只是提一下.Flex在多层结构中的一些优势.
Okay废话就不说了,
在图中我们可以看到,C#的表现层,我们用Webservice替代,而C#的Model我们在Flex里建立一个镜像的Model.这样的一个最大的优点就是,我们在数据传输的时候,通过格式化后的model,两边都有一个实体与之对应,操作起来十分方便.例如,我们先看一下C#中的Web方法的写法:
----------------------------------------
----------------------------------------
/// <summary>
/// C# To Flex Model
/// </summary>
/// <returns>Model</returns>
[WebMethod]
public RedPill.Model.UserInfo Ws2Flex()
{} |
这样我们的返回值可以设置成我们的Model.而不用过去的方法:返回一个XMLDocument的类型.Webservice会按我们的定义返回一个序列化的XML.
我们再看一下C#的Model的结构:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace RedPill.Model
{
/// <summary>
/// User Info Model.
/// </summary>
public class UserInfo
{
public UserInfo()
{
}
private Int32 m_ID;
private Boolean m_IsForPublic; //是否公开
private String m_UserName; //用户姓名
private String m_UserPassword; //用户密码
private String m_UserTrueName; //真实姓名
public Int32 ID
{
get { return m_ID; }
set { m_ID = value; }
}
///<summary>
///是否公开
///</summary>
public Boolean IsForPublic
{
get { return m_IsForPublic; }
set { m_IsForPublic = value; }
}
///<summary>
///用户姓名
///</summary>
public String UserName
{
get { return m_UserName; }
set { m_UserName = value; }
}
///<summary>
///用户密码
///</summary>
public String UserPassword
{
get { return m_UserPassword; }
set { m_UserPassword = value; }
}
///<summary>
///真实姓名
///</summary>
public String UserTrueName
{
get { return m_UserTrueName; }
set { m_UserTrueName = value; }
}
}
} |
很容易看懂,全是Get Set. 因为本身Model只是信息的承载体,因此里面不放任何逻辑处理.这样相当于是什么呢?就相当于,我们每个人传递的东西都是一个被打了包的东西,我们不一个一个的传递包内的内容,我们只关心这个包的本身的传递.
回到我们C#的方法里来:
/// <summary>
/// C# To Flex Model
/// </summary>
/// <returns>Model</returns>
[WebMethod]
public RedPill.Model.UserInfo Ws2Flex()
{
UserInfo rt = new UserInfo();
rt.ID = 0;
rt.IsForPublic = true;
rt.UserName = "http://ezse.com";
rt.UserPassword = "How 2 Use Model In Flex";
rt.UserTrueName = "Shawn";
return rt;
}
/// <summary>
/// Flex Model To C#
/// </summary>
/// <param name="rt">Model</param>
[WebMethod]
public void Flex2Ws(UserInfo rt)
{
Debug.WriteLine("ID:" + rt.ID.ToString());
Debug.WriteLine("Is for public?:" + rt.IsForPublic.ToString());
Debug.WriteLine("User Name:" + rt.UserName);
Debug.WriteLine(" WD:" + rt.UserPassword);
Debug.WriteLine("True Name:" + rt.UserTrueName);
} |
两个方法分别功能是向Flex返回一个model,另一个是把Flex给C#的model输出出来.很简单的功能.
然后我们再看一下invoke Webservice返回的数据形态:
<UserInfo>
<ID>0</ID>
<IsForPublic>true</IsForPublic>
<UserName>http://ezse.com</UserName>
<UserPassword>How 2 Use Model In Flex</UserPassword>
<UserTrueName>Shawn</UserTrueName>
</UserInfo> |
在Flex中,我们建立两个三个类,一个是ServiceLocator,它标明我们的服务地址.向程序提供服务.
二是TokenResponder 它是实现IResponder接口的,它功能是把所有的错误信息都统一输出.
三是我们的Model映像. UserInfo.前两个类,请看最后的源程序,我就不用多说了,我只是把关键的Model和主程序放出来说明:
好,现在我们看一下UserInfo.as的内容:
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2005-2006 RedPill.
// Name: Flex web service Model Transf.
// Ver: -
// Author:YX.Shawn
// Create:Thu Nov 30 21:24:50 GMT+0800 2006
// Modify:
// Function:
// ***
// this is a demo for let everyone know how to transfer model between C# & Flex.
// And this demo is esp for 5 Layer design.
// (DF-> DAL ->BLL-> resentation)
// |->Model->|
// For much infomation ,pls leave ur suggestion to my blog: http://blog.ezse.com
// Or mail me: yx.shawn@gmail.com
//
// Enjoy.
// ***
//
////////////////////////////////////////////////////////////////////////////////
package Model
{
/**
* Here, you can modify something you need by datasouse.
* This way is esp for data type conversion.
* such as Date
* e.g.:
* var df ateFormatter = new DateFormatter();
* this[i] = new Date(Date.parse(df.format(source[i])));
*/
public class UserInfo
{
public function UserInfo(source:Object=null)
{
super();
if(source!=null)
{
for (var i:String in source)
{
try
{
if (i == "UserTrueName" && source[i] is String)
this[i] = source[i]+"_MDF";
else
this[i] = source[i];
}
catch(e:Error)
{
//ignore
}
}
}
}
/**
* define each vars use the same name as C# model
* to make sure web service can translate model
*/
public var ID:Number;
public var IsForPublic:Boolean;
public var UserName:String;
public var UserPassword:String;
public var UserTrueName:String;
}
} |
可以很容易的看出和C#的model一样的是,里面采用的变量及变量的类型是一致的.所以称之为C#里Model的镜像.
然后FLEX如何去和C#通信呢?这个最基础的内容,WebService的
import mx.rpc.AbstractService;
import Model.UserInfo;
import mx.rpc.AsyncToken;
import RPC.*;
private var service:AbstractService;
//Security.allowDomain("*");
private function init():void
{
service = RPC.ServiceLocator.getUserInfoService();
var token:AsyncToken = AsyncToken(service.Ws2Flex());
token.addResponder(new TokenResponder(onWsRespond,"Error Get Data"));
}
private function onWsRespond(md:Object):void
{
var us:UserInfo = new UserInfo(md.result);
trace("ID"+us.ID);
trace("IsForPublic"+us.IsForPublic);
trace("UserName"+us.UserName);
trace("UserPassword"+us.UserPassword);
trace("UserTrueName"+us.UserTrueName);
trace("==============================");
trace("Change userTrueName to YX.Shawn. and call web service back...");
us.UserTrueName = "YX.Shawn";
var token:AsyncToken = AsyncToken(service.Flex2Ws(us));
} |
在init的方法里,我们通过异步调用,去调用我们在C#里写的Webservice的方法.在返回的监听方法里,我们通过图中高亮的那句话var us:UserInfo = new UserInfo(md.result);把返回的Model和Flex的Model进行对应.然后再修改参数后,回传到C#中.我们来看一下输出:
Flex输出 |
ID0
IsForPublictrue
UserNamehttp://ezse.com
UserPasswordHow 2 Use Model In Flex
UserTrueNameShawn_MDF
==============================
Change userTrueName to YX.Shawn. and call web service back... |
C#输出 |
ID:0
Is for public?:True
User Name:http://ezse.com
PWD:How 2 Use Model In Flex True Name:YX.Shaw |
观察输出会发现,在Flex里的输出里,TrueName多了_MDF,原因是我们在Model里做了一些调整,这个可以用于例如时间的类型转换呀一类的.回传的TrueName也变成了YX.Shawn.因此所有功能都实现.
可见,两边互传数据显得十分的简单.在C#也可以把Flex的model直接充当参数传递.
下面我就放上程序以及数据传递框架图
源程序下载地址:http://res.ezse.com/Howto/HowTo-Model.rar