WebApi的Swagger中实现area分级Controller

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xxdddail/article/details/81868721

Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升。但是使用Swagger时如果只是一般的控制器直接放到Controller下就可以了,而如果因不同的业务需求而需要分类或者有同名的类名时时则没办法很好的处理,有的人是在Controller下直接手动以不同的前缀或者后缀来区分,有的是只能改成其他的名字,总之用起来有点别扭。Asp.Net提供了区域来划分的方法,但是区域划分了之后,Swagger却没有直接根据路由的模板来解析出所期望的url。

    //注册路由映射
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{area}/{controller}/{action}/{id}",//action表示按方法路由
                defaults: new { id = RouteParameter.Optional }
            );

默认情况下,area是被作为参数来输入的,这样的请求用起来很别扭。那有什么办法可以改善呢?

经过反复测试,发现可以通过在SwaggerConfig.cs中启用c.GroupActionBy,然后在内部作相应的处理。

这里我用c.GroupActionsBy(apiDesc =>apiDesc.GetAreaName()),其中GetAreaName是ApiDescription的扩展方法,其实现如下

using System.Linq;
using System.Text.RegularExpressions;

namespace System.Web.Http.Description
{
    /// <summary>
    /// API描述器扩展
    /// </summary>
    public static class ApiDescriptionExtension
    {
        /// <summary>
        /// 获取区域名称
        /// </summary>
        /// <param name="description"></param>
        /// <returns></returns>
        public static string GetAreaName(this ApiDescription description)
        {
            string controllerFullName = description.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
            //匹配areaName
            string areaName = Regex.Match(controllerFullName, @"Area.([^,]+)\.C").Groups[1].ToString().Replace(".", "");
            if (string.IsNullOrEmpty(areaName))
            {
                //若不是areas下的controller,将路由格式中的{area}去掉
                description.RelativePath = description.RelativePath.Replace("{area}/", "");
            }
            else
            {
                //若是areas下的controller,将路由格式中的{area}替换为真实areaname
                description.RelativePath = description.RelativePath.Replace("{area}", areaName);
                var findResult = description.ParameterDescriptions.Where(t => t.Name == "area");
                if (findResult != null && findResult.Count() > 0)
                {
                    description.ParameterDescriptions.Remove(findResult.First());
                }
            }
            return areaName;
        }
    }
}

通过控制器来获取区域的名称,然后修改ApiDescription的相对路径RelativePath,这个路径会在Swagger界面上显示,再将参数列表ParameterDescriptions中的area参数移除掉,需要注意的是如果控制器的方法中有area参数的,也有可能被移除,所以为了安全起见,最好不要用area作为方法的参数名称。

同时,c.GroupActionsBy(apiDesc =>apiDesc.GetAreaName())也实现了用区域名称来区分api各个接口,一举多得。最终结果如下:

以上需要使用NuGet安装Swashbuckle、Swagger-Net、Miscrosoft.AspNet.Mvc,配置项目生成xml,配置SwaggerConfig读取api描述的xml,相关的配置图如下

源码下载

转载请注明出处

猜你喜欢

转载自blog.csdn.net/xxdddail/article/details/81868721