ASP.NET Web Api 如何使用 Swagger 管理 API

简介: ASP.NET Web Api 如何使用 Swagger 管理 API

前言

Swagger 是一个开源的框架,支持 OpenAPI 规范,可以根据 API 规范自动生成美观的、易于浏览的 API 文档页面,包括请求参数、响应示例等信息,并且,Swagger UI 提供了一个交互式的界面,可以帮助我们快速测试和调试 API,验证 API 的功能和正确性。

总的来说,Swagger 是一个强大的工具,可以帮助开发人员设计、构建和文档化 RESTful API,提高 API 的可读性、可维护性和互操作性,有了它,我们就可以更方便、更有效率地管理 API。

在 ASP.NET Core 中,已经内置了 Swagger,很方便就能使用。但在 ASP.NET 里,需要我们自己引用和配置才能使用它,下面通过一个 Step By Step 例子来看看 ASP.NET Web Api 如何使用 Swagger。

Step By Step 步骤

  1. 创建 .netframework webapi 项目
  2. 在项目上右键 - 项目属性 - 生成 - (输出)勾选 “XML文档文件"并填写自定义路径如"App_Data\apidoc.xml”
  3. Nuget 安装以下 Swagger 相关的两个包

Swashbuckle

Swagger.NET.UI(这个不装也可以)

4.创建 App_Start/SwaggerCacheProvider 辅助类,用于获取 xml 文件注释内容,留意注释

using Swashbuckle.Swagger;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
namespace SwaggerTest
{
  /// <summary>
  /// 支持方法注释
  /// </summary>
  public class SwaggerCacheProvider : ISwaggerProvider
  {
    private readonly ISwaggerProvider _swaggerProvider;
    private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
    private readonly string _xmlPath;
    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="swaggerProvider"></param>
    /// <param name="xmlpath"></param>
    public SwaggerCacheProvider(ISwaggerProvider swaggerProvider, string xmlpath)
    {
      _swaggerProvider = swaggerProvider;
      _xmlPath = xmlpath;
    }
    /// <summary>
    /// 生成 Swagger 文档,并存入缓存
    /// </summary>
    /// <param name="rootUrl"></param>
    /// <param name="apiVersion"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
    {
      var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
      // 只读取一次
      if (!_cache.TryGetValue(cacheKey, out SwaggerDocument srcDoc))
      {
        srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
        srcDoc.vendorExtensions = new Dictionary<string, object>
        {
          { "ControllerDesc", GetControllerDesc() }
        };
        _cache.TryAdd(cacheKey, srcDoc);
      }
      return srcDoc;
    }
    /// <summary>
    /// 从API文档中读取控制器描述
    /// </summary>
    /// <returns></returns>
    private ConcurrentDictionary<string, string> GetControllerDesc()
    {
      ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
      if (File.Exists(_xmlPath))
      {
        // 1. 加载生成 xml
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(_xmlPath);
        // 2. 读取控制器方法注释内容
        string[] arrPath;
        int cCount = "Controller".Length;
        foreach (XmlNode node in xmldoc.SelectNodes("//member"))
        {
          string type = node.Attributes["name"].Value;
          if (type.StartsWith("T:"))
          {
            arrPath = type.Split('.');
            string controllerName = arrPath[arrPath.Length - 1];
            if (controllerName.EndsWith("Controller"))  //控制器
            {
              // 获取控制器注释
              XmlNode summaryNode = node.SelectSingleNode("summary");
              string key = controllerName.Remove(controllerName.Length - cCount, cCount);
              if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
              {
                controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
              }
            }
          }
        }
      }
      return controllerDescDict;
    }
  }
}

5.创建 Scripts\swagger.js,用于支持显示中文注释内容

'use strict';
window.SwaggerTranslator = {
  _words: [],
  translate: function () {
    var $this = this;
    $('[data-sw-translate]').each(function () {
      $(this).html($this._tryTranslate($(this).html()));
      $(this).val($this._tryTranslate($(this).val()));
      $(this).attr('title', $this._tryTranslate($(this).attr('title')));
    });
  },
  setControllerSummary: function () {
    $.ajax({
      type: "get",
      async: true,
      url: $("#input_baseUrl").val(),
      dataType: "json",
      success: function (data) {
        var summaryDict = data.ControllerDesc;
        var id, controllerName, strSummary;
        $("#resources_container .resource").each(function (i, item) {
          id = $(item).attr("id");
          if (id) {
            controllerName = id.substring(9);
            strSummary = summaryDict[controllerName];
            if (strSummary) {
              $(item).children(".heading").children(".options").first().prepend('<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
            }
          }
        });
      }
    });
  },
  _tryTranslate: function (word) {
    return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
  },
  learn: function (wordsMap) {
    this._words = wordsMap;
  }
};
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
  "Warning: Deprecated": "警告:已过时",
  "Implementation Notes": "实现备注",
  "Response Class": "响应类",
  "Status": "状态",
  "Parameters": "参数",
  "Parameter": "参数",
  "Value": "值",
  "Description": "描述",
  "Parameter Type": "参数类型",
  "Data Type": "数据类型",
  "Response Messages": "响应消息",
  "HTTP Status Code": "HTTP 状态码",
  "Reason": "原因",
  "Response Model": "响应模型",
  "Request URL": "请求 URL",
  "Response Body": "响应体",
  "Response Code": "响应码",
  "Response Headers": "响应头",
  "Hide Response": "隐藏响应",
  "Headers": "头",
  "Try it out!": "试一下!",
  "Show/Hide": "显示/隐藏",
  "List Operations": "显示操作",
  "Expand Operations": "展开操作",
  "Raw": "原始",
  "can't parse JSON.  Raw result": "无法解析 JSON。原始结果",
  "Model Schema": "模型架构",
  "Model": "模型",
  "apply": "应用",
  "Username": "用户名",
  "Password": "密码",
  "Terms of service": "服务条款",
  "Created by": "创建者",
  "See more at": "查看更多:",
  "Contact the developer": "联系开发者",
  "api version": "api 版本",
  "Response Content Type": "响应 Content Type",
  "fetching resource": "正在获取资源",
  "fetching resource list": "正在获取资源列表",
  "Explore": "浏览",
  "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",
  "Can't read from server.  It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置 access-control-origin。",
  "Please specify the protocol for": "请指定协议:",
  "Can't read swagger JSON from": "无法读取 swagger JSON于",
  "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染 Swagger UI",
  "Unable to read api": "无法读取 api",
  "from path": "从路径",
  "server returned": "服务器返回"
});
$(function () {
  window.SwaggerTranslator.translate();
  window.SwaggerTranslator.setControllerSummary();
});

6.右键 Scripts\swagger.js - 属性 - 生成操作 - 改为 “嵌入的资源”

7.打开并修改 App_Start\SwaggerConfig.cs(安装以上包后自动生成此文件),以下是修改后的完整代码

using System.Web.Http;
using WebActivatorEx;
using SwaggerTest;
using Swashbuckle.Application;
using System.Reflection;
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace SwaggerTest
{
  // 完整版 Swagger config 代码
  /// <summary>
  /// 配置 Swagger
  /// </summary>
  public class SwaggerConfig
  {
    /// <summary>
    /// 注册
    /// </summary>
    public static void Register()
    {
      var thisAssembly = typeof(SwaggerConfig).Assembly;
      GlobalConfiguration.Configuration
        .EnableSwagger(c =>
          {
            //用于启用和设置Swagger的配置信息。
            c.SingleApiVersion("v2", "测试 API 接口文档");
            c.IncludeXmlComments($@"{System.AppDomain.CurrentDomain.BaseDirectory}\bin\SwaggerTest.xml");
            //获取项目指定路径下xml文件
            c.CustomProvider((defaultProvider) => new SwaggerCacheProvider(defaultProvider, $@"{System.AppDomain.CurrentDomain.BaseDirectory}\bin\SwaggerTest.xml"));
          })
        .EnableSwaggerUi(c =>
          {
            //用于启用UI界面上的东西。
            //加载汉化的js文件,注意 swagger.js文件属性必须设置为“嵌入的资源”。 APIUI.Scripts.swagger.js依次是:项目名称->文件夹->js文件名 
            c.InjectJavaScript(Assembly.GetExecutingAssembly(), "SwaggerTest.Scripts.swagger.js");
          });
    }
  }
}

8.打开并注释掉 App_Start\SwaggerNet.cs 代码(安装以上包后自动生成此文件)

using System;
using System.IO;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;
using System.Web.Http.Dispatcher;
using System.Web.Routing;
using Swagger.Net;
//[assembly: WebActivator.PreApplicationStartMethod(typeof(SwaggerTest.App_Start.SwaggerNet), "PreStart")]
//[assembly: WebActivator.PostApplicationStartMethod(typeof(SwaggerTest.App_Start.SwaggerNet), "PostStart")]
namespace SwaggerTest.App_Start 
{
  /// <summary>
  /// Swagger Net 
  /// </summary>
  public static class SwaggerNet 
  {
    //public static void PreStart() 
    //{
    //    RouteTable.Routes.MapHttpRoute(
    //        name: "SwaggerApi",
    //        routeTemplate: "api/docs/{controller}",
    //        defaults: new { swagger = true }
    //    );            
    //}
    
    //public static void PostStart() 
    //{
    //    var config = GlobalConfiguration.Configuration;
    //    config.Filters.Add(new SwaggerActionFilter());
      
    //    try
    //    {
    //        config.Services.Replace(typeof(IDocumentationProvider),
    //            new XmlCommentDocumentationProvider(HttpContext.Current.Server.MapPath("~/bin/SwaggerTest.XML")));
    //    }
    //    catch (FileNotFoundException)
    //    {
    //        throw new Exception("Please enable \"XML documentation file\" in project properties with default (bin\\SwaggerTest.XML) value or edit value in App_Start\\SwaggerNet.cs");
    //    }
    //}
  }
}

9.至此,Swagger 配置就完成了,接着就可以运行看看效果了

测试

  • 配置完成后,直接运行项目,打开以下网址,即可看到效果
https://localhost:44335/swagger/

其它

  • Swagger.NET.UI不是必要的,运行 SwaggerUI目录下面的 index 反而会出错

我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊人生。

都看到这了,求个点赞、关注、在看三连呗,感谢支持。


目录
打赏
0
1
1
0
37
分享
相关文章
在 .NET 9 中使用 Scalar 替代 Swagger
在 .NET 9 中使用 Scalar 替代 Swagger
99 29
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 "魔法师",用它来管理对象的生命周期,让你的代码更加模块化、易于测试和维护
155 4
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
详解Swagger:Spring Boot中的API文档生成与测试工具
详解Swagger:Spring Boot中的API文档生成与测试工具
277 4
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
108 3
【Azure API 管理】是否可以将Swagger 的API定义导入导Azure API Management中
【Azure API 管理】是否可以将Swagger 的API定义导入导Azure API Management中
|
8月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
114 0
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
104 0
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
101 0
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
364 0
分享一个 ASP.NET Web Api 上传和读取 Excel的方案
分享一个 ASP.NET Web Api 上传和读取 Excel的方案
232 0

热门文章

最新文章