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


    一、需求及原因

    最近在做个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了解有很多不足,所以上述可能会有不对或不足之处,望后续阅者指正,或自己补足

  • 相关阅读:
    HA分布式集群二hive配置
    win下写任务提交给集群
    win10下将spark的程序提交给远程集群中运行
    Scala快学笔记(三)
    Scala快学笔记(二)
    Scala快学笔记(一)
    统计学习方法 三 kNN
    统计学习方法 二 感知机
    fluent python(一)
    Codewar (1)
  • 原文地址:https://www.cnblogs.com/xbj-hyml/p/14871855.html
Copyright © 2020-2023  润新知