Smark.Web逻辑方法代理
为了方便表述还是举个例子容易好理解,看下以逻辑方法
[Service]
public class CustomerService
{
public IList<Customer> List(string matchCompanyName,string country, [Output]DataPage datapage)
{
Expression exp = new Expression();
if (!string.IsNullOrEmpty(matchCompanyName))
exp &= Customer.contactName.Match(matchCompanyName);
if (!string.IsNullOrEmpty(country))
exp &= Customer.country == country;
datapage.RecordCount = exp.Count<Customer>();
return exp.List<Customer>(new Region(datapage.PageIndex,datapage.PageSize));
}
}
[Service]是Smark.Service的一个属性标识,描述该类接收容器托管;容器会托管他所有Public的实例方法。
Smark.Web对以上方法代理需要作些配置:
<configSections>
<section name="smarkweb" type="Smark.Web.SmarkWebSection,Smark.Web"/>
</configSections>
<smarkweb>
<Assembly>
<add type="DataSearchDome.Services"/>
<add type="Smark.Web"/>
</Assembly>
</smarkweb>
<httpHandlers>
<clear/>
<add verb="*" path="/business.aspx" type="Smark.Web.BusinessServiceHandler,Smark.Web"/>
</httpHandlers>
<httpModules>
<clear/>
<add name="smarkmodel" type="Smark.Web.SmarkHttpModel,Smark.Web"/>
</httpModules>
其核心部分就是定义一个HttpHandler来接管这些请求,所有这些请求的信息都由容器接管分析后再转接调用相关方法。既然由HttpHandler来接管,那么在Get或Post时内容必须有规范的格式。
business.aspx?method=CustomerService_List
method参数用来描述调用逻辑方法以[类_方法名],不过可以改造HttpHandler来把这参数简化;对于方法的参数则由request.params来提供,通过Smark.Service.Binders提供的功能进行参数数据自动绑定。组件除了提供一些基础的类型绑定功能外还提供自定义绑定功能,开发人员可以根据自己的需要把request.params提供的数据转换成任何对象,如文件上传数据等。由于现有设计方法描述上有缺陷,导致不支持重载方法映射。
接下来看其他应用平台如何通过Http来调用这个方法,这段时间在用Flex为了方便就用AS的HttpService来请求相关逻辑方法。首先在AS中定义方法代理对象:
public dynamic class CustomerService_List
{
public var Callback:Function;
public var matchCompanyName:Object;
public var country:Object;
public var PageIndex:Object;
public var PageSize:Object;
public var RecordCount:Object;
public var PageCount:Object;
public var OrderField:Object;
public function Execute(method:String="get"):void
{
this._TimeSlice = new Date();
Utility.CallMethod("CustomerService_List",this,Callback,method);
}
}
以下是Utility.CallMethod方法代码
public static function CallMethod(methodurl:String,parameter:Object=null,callback:Function=null,method:String="get"):void
{
var httprequest:HTTPService;
httprequest = new HTTPService();
httprequest.useProxy=false;
httprequest.url= APP_URL+"business.aspx?method=" + methodurl;
httprequest.resultFormat="e4x";
httprequest.method=method;
…
if(parameter ==null)
parameter = new Object();
parameter._TimeSlice = new Date();
httprequest.send(parameter);
}
对于方法参数绑定是通过ParamName来进行约束的,如PageIndex自动会映射到DataPage.PageIndex属性上。如果多个参数对象都存在相同属性名称,那就要通过前缀来区分;如dp_PageIndex,那参在服务端参数定义就要加上前缀描述:[Bind(Prefix="dp")]DataPage datapage。细心的朋友会看到datapage参数里有个Output属性描述,这个属性描述除了返回值要输出外,datapage这个参数也要输出。
以下是实际运行返回的数据:
<Result>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Customer>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
<ContactName>Maria Anders</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Address>Obere Str. 57</Address>
<City>
<PostalCode>12209</PostalCode>
<Country>
<Phone>030-0074321</Phone>
<Fax>030-0076545</Fax>
</Customer>
</Data>
<Properties>
<datapage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PageIndex>0</PageIndex>
<PageSize>10</PageSize>
<RecordCount>91</RecordCount>
</datapage>
</Properties>
<Exception />
</Result>
拦载器
前面说过Smark.Web提供代理方法的拦载器功能,在这里也顺便介绍一下相关功能。拦载器的作用主要是方便开发人员根据实际情况的需要,对方法的调用处理进行控制:如修改参数内容,取消方法调用,修改方法返回值和统一处理异常等等。
以下是设置数据库信息的拦载器
public class SetConnectionString :Smark.Service.Intercept
{
#region IIntercept 成员
static bool IsChangeConnection = false;
public void Execute(Smark.Service.MethodContext context)
{
if (!IsChangeConnection)
{
string dbpath = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}app_data\Northwind.mdb";
DBContext.SetConnectionString(ConnectionType.Context1, string.Format(dbpath, MVCContext.Current.Http.Request.PhysicalApplicationPath));
IsChangeConnection = true;
}
context.Execute();
}
protected override void OnInit()
{
}
}
以上拦载器会对所有代理方法有效,无论那个方法调用都会触发到该拦载器。
让拦载器只用于某一类型方法:
protected override void OnInit()
{
CreateFilter<CustomerService>("List");
}
让拦载器不用于某一类型方法:
protected override void OnInit()
{
CreateSkipFilter<CustomerService>("List");
}
到这里Smark.Web代理方法功能大概描述完成。有兴趣的朋友可以到:http://smarkweb.codeplex.com/下载源码了解。
具体应用:http://www.cnblogs.com/henryfan/archive/2009/07/27/1532512.html
http://www.nbao.net