Nancy2.0引入Swagger并设置其为嵌入的资源

因为项目需求,需要在Nancy的基础上引入Swagger,万能的互联网上有现成的方案, 方案写的很详细,实际按文档也成功的实现了相应的功能,但因为我是在基础dll里包含了该功能,所以我希望swagger-ui是作为嵌入的资源,就跟Swashbuckle.AspNetCore一样,使用的时候只要简单的声明相关代码,而且在最终的发布目录里面,也不需要包含swagger-ui相关的目录。

参考Swashbuckle.AspNetCore的相关代码SwaggerUIMiddleware,发现swagger-ui的静态资源文件是通过StaticFileMiddleware来实现的,这是一个很值得参考的思路。虽然Nancy没有Middleware,但它作为一个开源项目,肯定存在类似的功能实现。

首先我先下载了Nancy.Swagger源码以及它的官方帮助文档,期望从中找到它是否支持将swagger-ui作为嵌入的资源,但很遗憾,它设计思路上就是不支持!

于是我只能通过各种可能的关键字(嵌入资源、Embedded Resource等)在网上各种查找,终于找到了相关实现ResourceBootstrapper,原本我以为这是第三方实现,结果在Nancy源码中,我居然发现需要用到的EmbeddedStaticContentConventionBuilder是已经存在了的!唯一有些差异的是,找到的例子代码是基于Nancy1.x的,而我们项目中用的是Nancy 2.0,不过略微摸索过后,最终还是成功的接入了此部分!

最终相关代码部分如下,通过自定义NancyBootstrapper类,注意ResourceViewLocationProvider.RootNamespaces.Add方法用到的命名空间需要按实际调整

    public class CustomBootstrapper : DefaultNancyBootstrapper
    {
        protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
        {
            base.ApplicationStartup(container, pipelines);
            //设置Nancy Swagger相关信息
            Nancy.Swagger.Services.SwaggerMetadataProvider.SetInfo("你的SwaggerTitle", "你的SwaggerVersion", "你的NancyHostSetting.SwaggerDesc");
            //强制指定是当前类所在的Assembly
            ResourceViewLocationProvider.RootNamespaces.Add(typeof(CustomBootstrapper).Assembly, "你嵌入的资源View所在的命名空间");
        }

        protected override Func<ITypeCatalog, NancyInternalConfiguration> InternalConfiguration
        {
            get
            {
                return NancyInternalConfiguration.WithOverrides(config =>
                {
                    config.ViewLocationProvider = typeof(ResourceViewLocationProvider);
                });
            }
        }

        //protected override Func<ITypeCatalog, NancyInternalConfiguration> InternalConfiguration => category =>
        //{
        //    var config = NancyInternalConfiguration.Default(category);
        //    config.ViewLocationProvider = typeof(ResourceViewLocationProvider);
        //    return config;
        //};

        protected override void ConfigureConventions(NancyConventions nancyConventions)
        {
            //设置静态资源路径
            var resource = EmbeddedStaticContentConventionBuilder.AddDirectory("/swagger-ui", typeof(CustomBootstrapper).Assembly);
            //typeof(CustomBootstrapper).Assembly 强制指定是当前类的Assembly
            //不能用this.GetType().Assembly,如果有新的Bootstrapper继承自当前类,那么this.GetType().Assembly获取到的是子类的Assembly
            nancyConventions.StaticContentsConventions.Add(resource);
            base.ConfigureConventions(nancyConventions);
        }
    }

而嵌入的资源部分呢,则简单的配置如下

  <ItemGroup>
    <EmbeddedResource Include="swagger-ui/**/*" Exclude="swagger-ui/*.map;swagger-ui/*.json;swagger-ui/*.md" />
  </ItemGroup>

有一点要注意的是,当存在多个INancyBootstrapper,且存在多级继承时,会出现无法识别继承关系的问题报错Located multiple bootstrappers,需要通过NancyBootstrapperLocator.Bootstrapper = new SomeCustomBootstrapper() 来指定。

补充下swagger-uiindex调整

<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui/swagger-ui.css" />
    <link rel="stylesheet" type="text/css" href="./swagger-ui/index.css" />
    <link rel="icon" type="image/png" href="./swagger-ui/favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="./swagger-ui/favicon-16x16.png" sizes="16x16" />
</head>

<body>
    <div id="swagger-ui"></div>
    <script src="./swagger-ui/swagger-ui-bundle.js" charset="UTF-8"></script>
    <script src="./swagger-ui/swagger-ui-standalone-preset.js" charset="UTF-8"></script>
    <script type="text/javascript">
          window.onload = function () {
              //<editor-fold desc="Changeable Configuration Block">

              // the following lines will be replaced by docker/configurator, when it runs in a docker-container
              window.ui = SwaggerUIBundle({
                  url: "@Model",
                  dom_id: '#swagger-ui',
                  deepLinking: true,
                  presets: [
                      SwaggerUIBundle.presets.apis,
                      SwaggerUIStandalonePreset
                  ],
                  plugins: [
                      SwaggerUIBundle.plugins.DownloadUrl
                  ],
                  layout: "StandaloneLayout"
              });

              //</editor-fold>
          };

    </script>
</body>
</html>

swagger-ui在项目中的目录结构如下
在这里插入图片描述

其它资料
swagger-ui的源码:https://github.com/swagger-api/swagger-ui

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值