RESTful的.net webapi路由与URL的疑惑

第一次使用“ASP.NET MVC4 WebAPI”开发项目,只需使用WebAPI因为前端直接HTML+Ajax调用呈现。

疑惑1

各位大神是用什么优雅的姿势避免路由的增长(包括RouteAttribute注册的路由)?

按照 Visual Studio 给出的 WebAPI 路由和 ApiController 示例
要怎么实现如下获取客户开通的服务?

1、获取指定服务

请求方式&URL地址:[GET] http://*/api/service/服务编号

2、获取指定客户的所有服务

请求方式&URL地址:[GET] http://*/api/service/客户编号

难道只能这样写吗?

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "serviceID",
                routeTemplate: "api/{controller}/{serviceID}",
                defaults: new { serviceID = RouteParameter.Optional }
            );
            
            config.Routes.MapHttpRoute(
                name: "untID",
                routeTemplate: "api/{controller}/{untID}",
                defaults: new { untID = RouteParameter.Optional }
            );
        }
    }

    public class ServiceController : ApiController
    {
        //1、获取指定服务
        public ServiceEntity Get(string serviceID) {...}
        
        //2、获取指定客户的所有服务
        public IEnumerable<ServiceEntity> Get(string untID) {...}
    }

如果按照这种思路那岂不是要注册非常多的路由?

那么加入一个新API呢?

3、获取指定服务以及个性化配置值

请求方式&URL地址:[GET] http://*/api/service/full/服务编号
难道只能这样写吗?

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "serviceID",
                routeTemplate: "api/{controller}/{serviceID}",
                defaults: new { serviceID = RouteParameter.Optional }
            );
            
            config.Routes.MapHttpRoute(
                name: "untID",
                routeTemplate: "api/{controller}/{untID}",
                defaults: new { untID = RouteParameter.Optional }
            );
            
            config.Routes.MapHttpRoute(
                name: "action_serviceID",
                routeTemplate: "api/{controller}/{action}/{serviceID}",
                defaults: new { serviceID = RouteParameter.Optional }
            );
        }
    }
    
    public class ServiceController : ApiController
    {
        //1、获取指定服务
        public ServiceEntity Get(string serviceID) {...}
        
        //2、获取指定客户的所有服务
        public IEnumerable<ServiceEntity> Get(string untID) {...}
        
        //3、获取指定服务以及个性化配置值
        [HttpGet]
        public ServiceAndConfigModel Full(string serviceID) {...}
    }

疑惑2

按照网上RESTful介绍我的第三个API的URL地址应该是(/api/service/服务编号/config 或 /api/service/服务编号/config/配置编号)
针对这样的URL方法签名该怎么写呢?
难道这样写?

    public class ServiceController : ApiController
    {      
        //3、获取指定服务以及个性化配置值
        [HttpGet]
        [Route("service/{serviceID}/config")]
        public ServiceAndConfigModel Get(string serviceID) {...}
        
        [HttpGet]
        [Route("service/{serviceID}/config/{configID}")]
        public ServiceAndConfigModel Get(string serviceID, string configID) {...}
    }

我对.Net WebAPI 的了解仅是皮毛而已,在此我把我目前使用的解决方案也写出来,请大神指教。

我目前的解决方案

我目前使用的解决方案是GET请求的参数都放到"?"后面,URL参数名和Action的参数名必须一致。自己实现支持命名空间的ControllerSelector。

路由注册代码如下:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config)); //NamespaceHttpControllerSelector 是自己实现的类

            .... 添加 Filter 的代码。


            config.Routes.MapHttpRoute(
                name: "DefaultApiRoute",
                routeTemplate: "api/{controller}/{action}"
            );

            config.Routes.MapHttpRoute(
                name: "NamespaceApiRoute",
                routeTemplate: "api/{namespace}/{controller}/{action}"
            );

            config.Routes.MapHttpRoute(
                name: "Namespace2ApiRoute",
                routeTemplate: "api/{namespace}/{namespace2}/{controller}/{action}"
            );
        }
    }

请求的URL地址如下:
不知道还算不算是RESTful风格了。。。

1、获取指定服务
/api/unit/service/single?serviceID=服务编号
其中unit是命名空间名。

2、获取指定客户的所有服务
/api/unit/service/list?unitid=客户编号
其中unit是命名空间名。

3、获取指定服务以及个性化配置值
/api/unit/service/complete/single?serviceID=服务编号
其中unit和service是命名空间名。

Controllers代码如下:

namespace xxx.Controllers.Unit
{
    public class ServiceController : ApiController
    {
        //1、获取指定服务
        [HttpGet]
        public ServiceEntity Single(string serviceID) {...}
        
        //2、获取指定客户的所有服务
        [HttpGet]
        public IEnumerable<ServiceEntity> List(string untID) {...}
    }
}

namespace xxx.Controllers.Unit.Service
{
    public class CompleteController : ApiController
    {      
        //3、获取指定服务以及个性化配置值
        [HttpGet]
        public ServiceAndConfigModel Single(string serviceID) {...}
    }
}
阅读 3.2k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进