asp.net MVC4下同时启用默认路由及Web API,以及针对WebAPI 考虑接口分版本问题

时间:2021-06-11 17:31:42   收藏:0   阅读:0

一、需求及原因

最近在做个mvc(本人对mvc网站这块不熟)的项目维护,增加对外开放的API接口。本来项目里是有自己使用的api接口(采用mvc默认路由方式)流程的,准备依样画瓢,但领导提出需要考虑接口的规范化和版本管理。经过了解,mvc中有Web API功能,转为无页面API接口实现,故采用该方式

原来内部api格式:Api/{controller}/{action}/{id}           示例:/Api/ClientOpenApi/AjaxClientHeart;

新api格式:Api/{controller}/v1/{action}/{id}           示例:/Api/ClientOpenApi/v1/AjaxClientHeart;

 

二、问题1

   直接修改api路由格式,即添加版本v1段,导致原api无法识别。

   解决方式:修改前部api段,新api修改为  OpenApi/{controller}/v1/{action}/{id}  ,区分识别段

 

三、问题2

   如何区分版本好,即v1段。

  网上搜索相关问题时,比较方便的是在方法上利用路由特性字段标明,但貌似只有MVC5才具备??,故作罢。

  后续找到利用路由选择器,通过选择器解析请求URL中的版本段内容,去匹配相关的controller。参考 https://blog.csdn.net/weixin_30344995/article/details/99484427

具体实现

  (1) 编写2个controller 继承 web api特有的APIController基类,并且controller命名遵循 {controller}+V1+Controller规则,如下

  

public class ResourcesV1Controller : ApiController

public class ResourcesV2Controller : ApiController

 

(2)编写一个选择器类

 

  具体业务参考上述链接文档。其中在解析版本号时代码有做调整。原因是版本号是从URL路径中解析,而非请求参数

public class OPAPIVersionSelector:DefaultHttpControllerSelector
    {
        private HttpConfiguration _config;

        public OPAPIVersionSelector(HttpConfiguration config)
            : base(config)
        {
            _config = config;
        }
    
        //设计就是返回HttpControllerDesriptor的过程
        public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            //获取所有的controller键值集合
            var controllers = GetControllerMapping();
        
            //获取路由数据
            var routeData = request.GetRouteData();
        
            //从路由中获取当前controller的名称
            var controllerName = (string)routeData.Values["controller"];
        
            HttpControllerDescriptor descriptor = new HttpControllerDescriptor();
        
            //if(controllers.TryGetValue(controllerName, out descriptor))
            //{
                //var version = "2";
            
                //从QueryString中获取版本 
                var version = GetVersionFromQueryString(request);
            
                var newName = string.Concat(controllerName, "V", version);
            
                HttpControllerDescriptor versionedDescriptor;
            
                if(controllers.TryGetValue(newName, out versionedDescriptor))
                {
                    return versionedDescriptor;
                }
            
                return descriptor;
            //}
        
            return null;
        
        }
    
        //从QueryString中获取版本 
        private string GetVersionFromQueryString(HttpRequestMessage request)
        {
            string sPathAdnQuery = request.RequestUri.PathAndQuery.ToLower();
            if (!string.IsNullOrEmpty(sPathAdnQuery))
            {

                var arr = sPathAdnQuery.Split(/);
                if (arr.Length >= 5)
                {
                    if (arr[1] == "OpenApi" && arr[3].Contains("v"))
                    {
                        return arr[3].Substring(1);
                    }
                }

            }

            //var query = HttpUtility.ParseQueryString(request.RequestUri.Query);//此部分是要求版本作为参数传过来,而不是URL
            //var version = query["v"];
            //if(version != null)
            //{
            //    return version;
            //}
        
            return "1";
        }
    }

(3) 修改WebApiConfig.cs内容,如下

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "OPApiV1",
                routeTemplate: "OpenApi/{controller}/{ver}/{action}/{id}",
                defaults: new {  id = RouteParameter.Optional }

            );
            //config.Routes.MapHttpRoute(
            //    name: "OPApiV2",
            //    routeTemplate: "api/{controller}/v2/{action}/{id}",
            //    defaults: new { id = RouteParameter.Optional }

            //);
            //注册版本选择器
            config.Services.Replace(typeof(IHttpControllerSelector), new OPAPIVersionSelector(config));
        }
    }

(4) 在Global.asax.cs中,注册webapi

WebApiConfig.Register(GlobalConfiguration.Configuration);

(5) 请求完整URL示例:http://192.168.99.101:8090/OpenApi/Resources/v1/GetFileInfo

 

 (6) 在controller中获取post请求的body,此处要求body为json格式,并且需要有对应的Model匹配,如下

[HttpPost]
 public OPResponseBaseModel<List<OPResponseUserModel>> GetUserAndDepartmentInfo([FromBody]OPRequestParamBaseModel requestModel)
 {
  //your  code
 }

 

另外,本人对MVC了解有很多不足,所以上述可能会有不对或不足之处,望后续阅者指正,或自己补足

 

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!