好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使Web API支持二级实体操作,兼对RESTFul风格API设计的疑惑。

使Web API支持二级实体操作,兼对RESTFul风格API设计的疑惑。

最近一直在纠结应该创建RESTFul风格的API还是以前那种函数调用风格的API。如果创建RESTFul风格的API,又有很多设计问题有待理清,这暂且不论,在用Web API创建RESTFul风格的API的时候,对于二级实体操作又该如何设计API接口呢?比如一个Client实体,它有很多属于它的Order实体,而每个Order实体又有很多Product实体,API接口如何设计才能更好的体现这种关系和操作呢?如果大家对此有想法,欢迎留言为我解惑。

我目前尝试设计和实现一种层次性的API接口,我不确定这是否是最佳的做法,调用的时候看起来是这样的:

Route看起来是这样的:

/api/{controller}/{id}/{subController1}/{subID1}/{subController2}/{subID2}

当然,需要的话,可以继续往后追加subController3,4,5,6...

而Controller应该看起来是什么样子的呢?我的做法是,分别为Client、Order和Product建立Controller:

ClientsController

ClientsOrdersController

ClientsOrdersProductsConroller

这样我可以将以上3个Controller的名字映射到{controller}、{subController1}、{subController2},抽象一点说,就是Controller名字的每一部分对应映射中的一个{controller}/{subcontrollerX}.

剩下的一个问题就是如何让MVC引擎能将这个路由映射到正确的Controller上。我们都知道(其实我们不都知道,包括在研究这个问题之前的我),MVC引擎根据路由找Controller的操作之一要靠IHttpControllerSelector接口,默认情况下具体干活的就是DefaultHttpControllerSelector类,我要做的就是继承这个类,然后从路由数据中查看那些subController参数是否被映射上的具体数据,如果没有,就调用默认行为,如果有,就把所有的controller参数的值拼接成真正的controller名字返回,代码如下:

  1   using   System;
   2   using   System.Collections.Generic;
   3   using   System.Linq;
   4   using   System.Web.Http;
   5   using   System.Web.Http.Dispatcher;
   6   using   System.Net.Http;
   7   using   System.Web.Http.Routing;
   8  
  9   namespace   Ricky
  10   {
  11       public   class   HttpControllerSelectorEx : DefaultHttpControllerSelector
  12       {
  13           private   HttpConfiguration _HttpCfg;
  14  
 15           public   HttpControllerSelectorEx(HttpConfiguration cfg)
  16              :  base  (cfg)
  17           {
  18              _HttpCfg =  cfg;
  19           }
  20  
 21           public   override   string   GetControllerName(HttpRequestMessage request)
  22           {
  23               string  name =  base  .GetControllerName(request);
  24              IHttpRouteData routeData =  request.GetRouteData();
  25              IEnumerable<KeyValuePair< string ,  object >> subControllers =  routeData.Values
  26                  .Where(d => d.Key.StartsWith( "  subController  "  , StringComparison.CurrentCultureIgnoreCase));
  27               if  (subControllers.Count() ==  0  )
  28                   return   name;
  29  
 30              List< string > names =  new  List< string >( 1  +  subControllers.Count());
  31               names.Add(name);
  32               foreach  (KeyValuePair< string , object > subController  in   subControllers)
  33               {
  34                   names.Add(subController.Value.ToString());
  35               }
  36  
 37               return   string .Join( ""  , names);
  38           }
  39       }
  40  }

完成之后需要用我们的controller selector替换系统的默认设置。这在Global.asax.cs的Application_Start方法中做:

 1  GlobalConfiguration.Configuration.Services.Replace( typeof  (IHttpControllerSelector)
  2      ,  new  Ricky.HttpControllerSelectorEx(GlobalConfiguration.Configuration));

最后,我们修改一下路由设置:

  1   public   static   void   Register(HttpConfiguration config)
   2   {
   3       config.Routes.MapHttpRoute(
   4          name:  "  DefaultApiWithSubControllers  "  ,
   5          routeTemplate:  "  api/{controller}/{id}/{subController}/{subID}/{subController2}/{subID2}  "  ,
   6          defaults:  new 
  7           {
   8              id =  RouteParameter.Optional,
   9              subController =  RouteParameter.Optional,
  10              subID =  RouteParameter.Optional,
  11              subController2 =  RouteParameter.Optional,
  12              subID2 =  RouteParameter.Optional
  13           }
  14       );
  15  
 16       //  config.Routes.MapHttpRoute(
  17       //      name: "DefaultApi",
  18       //      routeTemplate: "api/{controller}/{id}",
  19       //      defaults: new { id = RouteParameter.Optional }
  20       //  ); 
 21  }

由于我们的路由设置其实是扩展默认设置的,因此可以注释掉原来的默认设置。

理解的越多,需要记忆的就越少

 

分类:  ASP.NET

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于使Web API支持二级实体操作,兼对RESTFul风格API设计的疑惑。的详细内容...

  阅读:42次