Asp.netCore WebApi初体验之搭建Swagger并在IIS上部署

1、新建.netCore webapi项目

2、安装swagger ,通过 Package Manager 控制台:Install-Package

 

 

 

3、Startup.cs中注册服务并添加至管道

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading.Tasks;
 5 using Microsoft.AspNetCore.Builder;
 6 using Microsoft.AspNetCore.Hosting;
 7 using Microsoft.AspNetCore.HttpsPolicy;
 8 using Microsoft.AspNetCore.Mvc;
 9 using Microsoft.Extensions.Configuration;
10 using Microsoft.Extensions.DependencyInjection;
11 using Microsoft.Extensions.Logging;
12 using Microsoft.Extensions.Options;
13 
14 namespace CoreTest
15 {
16     public class Startup
17     {
18         public Startup(IConfiguration configuration)
19         {
20             Configuration = configuration;
21         }
22         public IConfiguration Configuration { get; }
23         // This method gets called by the runtime. Use this method to add services to the container.
24         public void ConfigureServices(IServiceCollection services)
25         {
26             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
27 
28             //1、注册服务Swagger
29             services.AddSwaggerGen(options =>
30             {
31                 options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
32                 {
33                     Version = "v1",
34                     Title = "My API",
35                     Description = "by JiaJia"
36                 });
37             });
38         }
39         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
40         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
41         {
42             if (env.IsDevelopment())
43             {
44                 app.UseDeveloperExceptionPage();
45             }
46             else
47             {
48                 app.UseHsts();
49             }
50             app.UseHttpsRedirection();
51             app.UseMvc();
52 
53             //2、添加到管道
54             #if DEBUG
55             app.UseSwagger();
56             app.UseSwaggerUI(c =>
57             {
58                 c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
59                 // c.DocExpansion(DocExpansion.None);
60             });
61             #endif
62         }
63     }
64 }


4、访问 Swagger UI 地址

http://localhost:60238/swagger/index.html

 

 

 

5、添加备注

1)在项目属性的 生成 => 输出 中勾选 XML文档文件。

 

2)在 Start.cs => ConfigureServices 方法中的 AddSwaggerGen 处增加 IncludeXmlComments 处理。

 1 //1、注册服务Swagger
 2 services.AddSwaggerGen(options =>
 3 {
 4     options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
 5     {
 6         Version = "v1",
 7         Title = "My API",
 8         Description = "by JiaJia"
 9     });
10     //在 Start.cs => ConfigureServices 方法中的 AddSwaggerGen 处增加 IncludeXmlComments 处理。
11     options.IncludeXmlComments(string.Format("{0}/CoreTest.xml",
12     AppDomain.CurrentDomain.BaseDirectory));
13 
14     /*或者这种添加方式//为 Swagger JSON and UI设置xml文档注释路径
15     var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
16     var xmlPath = Path.Combine(basePath, "CoreTest.xml");//和项目名对应
17     options.IncludeXmlComments(xmlPath);*/
18 });

3)控制器对Action添加注释信息

 1 /// <summary>
 2 /// 根据ID获取用户信息
 3 /// </summary>
 4 /// <param name="id">用户ID</param>
 5 /// <returns>用户信息</returns>
 6 [HttpGet("{id}")]
 7 public ActionResult<string> Get(int id)
 8 {
 9     return "user info";
10 }

4)(指定输出路径默认空白,需要填写:bin\Debug\),而且默认的(CoreTest.xml)xml文件,与Startup的文件必须对应(否则会报错)

 

 5)不想每一个方法都这么加注释,可以这么配置(对当前项目进行配置,可以忽略警告,记得在后边加上分号 ;1591)

 

 

 

 

最终效果:

 

 

二、接口执行时间分析——MiniProfiler

搭建MiniProfiler

安装引入nuget包:

Install-Package MiniProfiler.AspNetCore.Mvc

 

 

然后,在startup.cs 中配置服务ConfigureServices:

1 //注册服务MiniProfiler
2 services.AddMiniProfiler(options =>
3 {
4 options.RouteBasePath = "/profiler";//注意这个路径要和下边 index.html 脚本配置中的一致,
5 (options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(10);
6 });

 

3、最后,调用下中间件即可:

1 //调用MiniProfiler中间件
2 app.UseMiniProfiler();

在 Swagger 中配置 MiniProfiler

上边我们在配置中已经启动了服务,接下来就需要设置如何在 swagger 中展示了,这个时候我们就需要自定义我们的swagger主页了,以前我们是用的默认的index.html,现在咱们需要自定义一个:

从官网 Github 上,下载最新的 index.html:https://github.com/swagger-api/swagger-ui/blob/master/dist/index.html

 1 <!-- HTML for static distribution bundle build -->
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>%(DocumentTitle)</title>
 7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 8     <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
 9     <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
10     <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
11     <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
12     <style>
13 
14 
15         html {
16             box-sizing: border-box;
17             overflow: -moz-scrollbars-vertical;
18             overflow-y: scroll;
19         }
20 
21         *,
22         *:before,
23         *:after {
24             box-sizing: inherit;
25         }
26 
27         body {
28             margin: 0;
29             background: #fafafa;
30         }
31     </style>
32     %(HeadContent)
33 </head>
34 <body>
35     <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
36         <defs>
37             <symbol viewBox="0 0 20 20" id="unlocked">
38                 <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
39             </symbol>
40             <symbol viewBox="0 0 20 20" id="locked">
41                 <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z" />
42             </symbol>
43             <symbol viewBox="0 0 20 20" id="close">
44                 <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z" />
45             </symbol>
46             <symbol viewBox="0 0 20 20" id="large-arrow">
47                 <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z" />
48             </symbol>
49             <symbol viewBox="0 0 20 20" id="large-arrow-down">
50                 <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z" />
51             </symbol>
52 
53             <symbol viewBox="0 0 24 24" id="jump-to">
54                 <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" />
55             </symbol>
56             <symbol viewBox="0 0 24 24" id="expand">
57                 <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
58             </symbol>
59         </defs>
60     </svg>
61     <div id="swagger-ui"></div>
62     <!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
63     <script>
64         if (window.navigator.userAgent.indexOf("Edge") > -1) {
65             console.log("Removing native Edge fetch in favor of swagger-ui's polyfill")
66             window.fetch = undefined;
67         }
68     </script>
69     <script src="./swagger-ui-bundle.js"></script>
70     <script src="./swagger-ui-standalone-preset.js"></script>
71     <script>
72         window.onload = function () {
73             var configObject = JSON.parse('%(ConfigObject)');
74             var oauthConfigObject = JSON.parse('%(OAuthConfigObject)');
75 
76             // Apply mandatory parameters
77             configObject.dom_id = "#swagger-ui";
78             configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
79             configObject.layout = "StandaloneLayout";
80 
81             // If oauth2RedirectUrl isn't specified, use the built-in default
82             if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
83                 configObject.oauth2RedirectUrl = window.location.href.replace("index.html", "oauth2-redirect.html");
84 
85             // Build a system
86             const ui = SwaggerUIBundle(configObject);
87 
88             // Apply OAuth config
89             ui.initOAuth(oauthConfigObject);
90         }
91     </script>
92 </body>
93 </html>

将该文件天机到项目中,并设置成嵌入资源的类型:

接下来,在 Index.html 文件中,增加配置脚本(我是在顶部写的,Head应该也可以):

<script async="async" id="mini-profiler" src="/profiler/includes.min.js?v=4.0.138+gcc91adf599"
        data-version="4.0.138+gcc91adf599" data-path="/profiler/"
        data-current-id="4ec7c742-49d4-4eaf-8281-3c1e0efa748a" data-ids="" data-position="Left"
        data-authorized="true" data-max-traces="15" data-toggle-shortcut="Alt+P"
        data-trivial-milliseconds="2.0" data-ignored-duplicate-execute-types="Open,OpenAsync,Close,CloseAsync">
</script>

包括参数比如版本,/profiler的路径,position的位置显示,authorized的是否权限,max-traces最多显示多少条(15)等等。

修改后的网页代码如下

<script async="async" id="mini-profiler" src="/profiler/includes.min.js?v=4.0.138+gcc91adf599"
        data-version="4.0.138+gcc91adf599" data-path="/profiler/"
        data-current-id="4ec7c742-49d4-4eaf-8281-3c1e0efa748a" data-ids="" data-position="Left"
        data-authorized="true" data-max-traces="15" data-toggle-shortcut="Alt+P"
        data-trivial-milliseconds="2.0" data-ignored-duplicate-execute-types="Open,OpenAsync,Close,CloseAsync">
</script>

<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>%(DocumentTitle)</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
    <style>


        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }

        *,
        *:before,
        *:after {
            box-sizing: inherit;
        }

        body {
            margin: 0;
            background: #fafafa;
        }
    </style>
    %(HeadContent)
</head>
<body>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
        <defs>
            <symbol viewBox="0 0 20 20" id="unlocked">
                <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
            </symbol>
            <symbol viewBox="0 0 20 20" id="locked">
                <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z" />
            </symbol>
            <symbol viewBox="0 0 20 20" id="close">
                <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z" />
            </symbol>
            <symbol viewBox="0 0 20 20" id="large-arrow">
                <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z" />
            </symbol>
            <symbol viewBox="0 0 20 20" id="large-arrow-down">
                <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z" />
            </symbol>

            <symbol viewBox="0 0 24 24" id="jump-to">
                <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" />
            </symbol>
            <symbol viewBox="0 0 24 24" id="expand">
                <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
            </symbol>
        </defs>
    </svg>
    <div id="swagger-ui"></div>
    <!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
    <script>
        if (window.navigator.userAgent.indexOf("Edge") > -1) {
            console.log("Removing native Edge fetch in favor of swagger-ui's polyfill")
            window.fetch = undefined;
        }
    </script>
    <script src="./swagger-ui-bundle.js"></script>
    <script src="./swagger-ui-standalone-preset.js"></script>
    <script>
        window.onload = function () {
            var configObject = JSON.parse('%(ConfigObject)');
            var oauthConfigObject = JSON.parse('%(OAuthConfigObject)');

            // Apply mandatory parameters
            configObject.dom_id = "#swagger-ui";
            configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
            configObject.layout = "StandaloneLayout";

            // If oauth2RedirectUrl isn't specified, use the built-in default
            if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
                configObject.oauth2RedirectUrl = window.location.href.replace("index.html", "oauth2-redirect.html");

            // Build a system
            const ui = SwaggerUIBundle(configObject);

            // Apply OAuth config
            ui.initOAuth(oauthConfigObject);
        }
    </script>
</body>
</html>

然后我们修改下中间件去调用我们这个 index.html 页面:

1 app.UseSwaggerUI(c =>
2 {
3     c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
4     // 将swagger首页,设置成我们自定义的页面,记得这个字符串的写法:解决方案名.index.html
5     c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("CoreTest.index.html");
6 });

配置使用静态资源文件的中间件

 app.UseStaticFiles();

完整的Startup.cs文件

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Reflection;
 5 using System.Threading.Tasks;
 6 using Microsoft.AspNetCore.Builder;
 7 using Microsoft.AspNetCore.Hosting;
 8 using Microsoft.AspNetCore.Mvc;
 9 using Microsoft.Extensions.Configuration;
10 using Microsoft.Extensions.DependencyInjection;
11 using Microsoft.Extensions.Logging;
12 using Microsoft.Extensions.Options;
13 using StackExchange.Profiling.Storage;
14 
15 namespace CoreTest
16 {
17     public class Startup
18     {
19         public Startup(IConfiguration configuration)
20         {
21             Configuration = configuration;
22         }
23         public IConfiguration Configuration { get; }
24         // This method gets called by the runtime. Use this method to add services to the container.
25         public void ConfigureServices(IServiceCollection services)
26         {
27             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
28             //1、注册服务Swagger
29             services.AddSwaggerGen(options =>
30             {
31                 options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
32                 {
33                     Version = "v1",
34                     Title = "My API",
35                     Description = "by JiaJia"
36                 });
37                 options.IncludeXmlComments(string.Format("{0}/CoreTest.xml", AppDomain.CurrentDomain.BaseDirectory));
38             });
39             //注册服务MiniProfiler
40             services.AddMiniProfiler(options =>
41             {
42                 options.RouteBasePath = "/profiler";//注意这个路径要和下边 index.html 脚本配置中的一致,
43                 (options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(10);
44             });
45         }
46 
47         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
48         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
49         {
50             if (env.IsDevelopment())
51             {
52                 app.UseDeveloperExceptionPage();
53             }
54             //2、Swagger添加到管道
55 #if DEBUG
56             app.UseSwagger();
57             app.UseSwaggerUI(c =>
58             {
59                 c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
60                 // 将swagger首页,设置成我们自定义的页面,记得这个字符串的写法:解决方案名.index.html
61                 c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("CoreTest.index.html");
62             });
63 #endif
64             //2、MiniProfiler添加到管道
65             app.UseMiniProfiler();
66 
67             app.UseMvc();
68         }
69     }
70 }

控制器代码

 1 /// <summary>
 2         /// 根据ID获取用户信息
 3         /// </summary>
 4         /// <param name="id">用户ID</param>
 5         /// <returns>用户信息</returns>
 6         [HttpGet("{id}")]
 7         public ActionResult<IEnumerable<string>> Get()
 8         {
 9             string url1 = string.Empty;
10             string url2 = string.Empty;
11             using (MiniProfiler.Current.Step("Get方法"))
12             {
13                 using (MiniProfiler.Current.Step("准备数据"))
14                 {
15                     using (MiniProfiler.Current.CustomTiming("SQL", "SELECT * FROM Config"))
16                     {
17                         // 模拟一个SQL查询
18                         Thread.Sleep(500);
19 
20                         url1 = "https://www.baidu.com";
21                         url2 = "https://www.sina.com.cn/";
22                     }
23                 }
24 
25 
26                 using (MiniProfiler.Current.Step("使用从数据库中查询的数据,进行Http请求"))
27                 {
28                     using (MiniProfiler.Current.CustomTiming("HTTP", "GET " + url1))
29                     {
30                         var client = new WebClient();
31                         var reply = client.DownloadString(url1);
32                     }
33 
34                     using (MiniProfiler.Current.CustomTiming("HTTP", "GET " + url2))
35                     {
36                         var client = new WebClient();
37                         var reply = client.DownloadString(url2);
38                     }
39                 }
40             }
41             return new string[] { "value1", "value2" };
42         }
View Code

现在已经配置好了 MiniProfiler 和 Swagger了,运行页面左上角

 

 

切面 MiniFilter分析

1、只需要在 AOP 日志记录中,配置 MiniProfiler 即可:

posted @ 2019-12-31 14:39  heyy1028  阅读(2555)  评论(0编辑  收藏  举报