Smark.Web逻辑方法代理

         通过Smark.WebHttp请求直接映射到逻辑方法,这个功能看上去有点象WCF,虽然并不具备WCF那样强大,不过组件提供的拦载器功能足以让开发人员方便控制自己的逻辑处理,加上调用起来非常简单只需要HttpGetPost请求即可。而服务暂时只支持XML类型返回,不过在设计上是完全可以支持任何格式输出,根据自己的需要实现IOutputHandler即可。

为了方便表述还是举个例子容易好理解,看下以逻辑方法

    [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来接管,那么在GetPost时内容必须有规范的格式。

business.aspx?method=CustomerService_List

method参数用来描述调用逻辑方法以[_方法名],不过可以改造HttpHandler来把这参数简化;对于方法的参数则由request.params来提供,通过Smark.Service.Binders提供的功能进行参数数据自动绑定。组件除了提供一些基础的类型绑定功能外还提供自定义绑定功能,开发人员可以根据自己的需要把request.params提供的数据转换成任何对象,如文件上传数据等。由于现有设计方法描述上有缺陷,导致不支持重载方法映射。

接下来看其他应用平台如何通过Http来调用这个方法,这段时间在用Flex为了方便就用ASHttpService来请求相关逻辑方法。首先在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>Berlin</City>

  <PostalCode>12209</PostalCode>

  <Country>Germany</Country>

  <Phone>030-0074321</Phone>

  <Fax>030-0076545</Fax>

</Customer>  <CustomerID>BOTTM</CustomerID>   <CompanyName>Bottom-Dollar Markets</CompanyName>   <ContactName>Elizabeth Lincoln</ContactName>

  <ContactTitle>Accounting Manager</ContactTitle>

  <Address>23 Tsawassen Blvd.</Address>

  <City>Tsawassen</City>

  <Region>BC</Region>

  <PostalCode>T2F 8M4</PostalCode>

  <Country>Canada</Country>

  <Phone>(604) 555-4729</Phone>

  <Fax>(604) 555-3745</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

posted on 2009-07-28 18:27  henry  阅读(1846)  评论(0编辑  收藏  举报

导航