ServiceStack.Api.Swagger SwaggerResourcesService,不包括以Route Parameter开头的路由

时间:2016-11-28 15:43:38

标签: servicestack swagger-ui

我正在使用Servicestack版本4.0.52.0和ServiceStack.Api.Swagger 4.0.0.0

我在serviceStack应用程序主机派生类(AppHostBase)中定义了具有可变路由参数的所有路由:配置方法

public class AppHost : AppHostBase
{
    public override void Configure(Funq.Container container)
    {
        //Infrastructure code goes here
        ....

        //Add routes
        Routes.Add<TestRequestDTO>("/{MyApplicationKey}/TestOperation/", "GET")
    }
}

虽然这些路由在ServiceStack元数据页面中可见,但是swagger UI不显示以MyApplicationKey开头的路由;深入挖掘代码库,我们在ServiceStack.Api.Swagger.SwaggerResourcesService.Get方法中找到了问题:

 [AddHeader(DefaultContentType = MimeTypes.Json)]
    [DefaultRequest(typeof(SwaggerResources))]
    [Restrict(VisibilityTo = RequestAttributes.None)]
    public class SwaggerResourcesService : Service
    {
        private readonly Regex resourcePathCleanerRegex = new Regex(@"/[^\/\{]*", RegexOptions.Compiled);
        internal static Regex resourceFilterRegex;

        internal static Action<SwaggerResourcesResponse> ResourcesResponseFilter { get; set; }

        internal const string RESOURCE_PATH = "/resource";

        public object Get(SwaggerResources request)
        {
            var basePath = base.Request.GetBaseUrl();

            var result = new SwaggerResourcesResponse
            {
                BasePath = basePath,
                Apis = new List<SwaggerResourceRef>(),
                ApiVersion = HostContext.Config.ApiVersion,
                Info = new SwaggerInfo
                {
                    Title = HostContext.ServiceName,
                }
            };
            var operations = HostContext.Metadata;
            var allTypes = operations.GetAllOperationTypes();
            var allOperationNames = operations.GetAllOperationNames();
            foreach (var operationName in allOperationNames)
            {
                if (resourceFilterRegex != null && !resourceFilterRegex.IsMatch(operationName)) continue;
                var name = operationName;
                var operationType = allTypes.FirstOrDefault(x => x.Name == name);
                if (operationType == null) continue;
                if (operationType == typeof(SwaggerResources) || operationType == typeof(SwaggerResource))
                    continue;
                if (!operations.IsVisible(Request, Format.Json, operationName)) continue;

                CreateRestPaths(result.Apis, operationType, operationName);
            }

            result.Apis = result.Apis.OrderBy(a => a.Path).ToList();

            if (ResourcesResponseFilter != null)
                ResourcesResponseFilter(result);

            return new HttpResult(result) {
                ResultScope = () => JsConfig.With(includeNullValues:false)
            };
        }

        protected void CreateRestPaths(List<SwaggerResourceRef> apis, Type operationType, string operationName)
        {
            var map = HostContext.ServiceController.RestPathMap;
            var feature = HostContext.GetPlugin<SwaggerFeature>();

            var paths = new List<string>();

            foreach (var key in map.Keys)
            {
                paths.AddRange(map[key].Where(x => x.RequestType == operationType).Select(t => **resourcePathCleanerRegex.Match**(t.Path).Value));
            }
 ......
}

有关我们如何解决问题的任何提示?有没有办法在进行资源列表时将MyApplicationKey的值告诉Swagger API?

1 个答案:

答案 0 :(得分:2)

通过在注册ResourcesResponseFilter插件时指定自定义SwaggerFeature,可以修改Swagger响应,例如:

Plugins.Add(new SwaggerFeature {
    ResourceFilterPattern = @"/[^\/\{]*",
    ResourcesResponseFilter = response => ...
});

这将允许您修改Swagger UI接收的Swagger响应。