asp.net web api傳送門:
- 跨域請求支援
- swagger線上接口文檔
- cookie身份驗證
前言
使用的開發工具為vs 2019
本文所使用的方法同樣适用于vs 2013建立的項目,親測有效
下載下傳swagger
打開NuGet包管理器,安裝圖中的包

準備工作
勾選XML文檔檔案後儲存退出
修改WebApiConfig檔案中的預設路由
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服務
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
//修改路由為控制器下的每個方法
routeTemplate: "api/{controller}/{action}",
defaults: new { id = RouteParameter.Optional }
);
}
}
顯示api接口注釋
在APP_Start檔案夾下建立一個SwaggerCacheProvider類
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 myFirst.App_Start
{
/// <summary>
/// 顯示swagger控制器的描述
/// </summary>
public class SwaggerControllerDescProvider : ISwaggerProvider
{
private readonly ISwaggerProvider _swaggerProvider;
private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
private readonly string _xml;
/// <summary>
///
/// </summary>
/// <param name="swaggerProvider"></param>
/// <param name="xml">xml文檔路徑</param>
public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
{
_swaggerProvider = swaggerProvider;
_xml = xml;
}
public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
{
var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
SwaggerDocument srcDoc = null;
//隻讀取一次
if (!_cache.TryGetValue(cacheKey, out 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>
public ConcurrentDictionary<string, string> GetControllerDesc()
{
string xmlpath = _xml;
ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
if (File.Exists(xmlpath))
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(xmlpath);
string type = string.Empty, path = string.Empty, controllerName = string.Empty;
string[] arrPath;
int length = -1, cCount = "Controller".Length;
XmlNode summaryNode = null;
foreach (XmlNode node in xmldoc.SelectNodes("//member"))
{
type = node.Attributes["name"].Value;
if (type.StartsWith("T:"))
{
//控制器
arrPath = type.Split('.');
length = arrPath.Length;
controllerName = arrPath[length - 1];
if (controllerName.EndsWith("Controller"))
{
//擷取控制器注釋
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;
}
}
}
漢化Swagger UI
定義一個JS檔案,做成嵌入資源,這個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 () {
try
{
console.log($("#input_baseUrl").val());
$.ajax({
type: "get",
async: true,
url: $("#input_baseUrl").val(),
dataType: "json",
success: function (data) {
var summaryDict = data.ControllerDesc;
console.log(summaryDict);
var id, controllerName, strSummary;
$("#resources_container .resource").each(function (i, item) {
id = $(item).attr("id");
if (id) {
controllerName = id.substring(9);
try {
strSummary = summaryDict[controllerName];
if (strSummary) {
$(item).children(".heading").children(".options").first().prepend('<li class="controller-summary" style="color:green;" title="' + strSummary + '">' + strSummary + '</li>');
}
} catch (e)
{
console.log(e);
}
}
});
}
});
}catch(e)
{
console.log(e);
}
},
_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();
});
将定義的js檔案屬性的生成操作更改為嵌入的資源
實作分組
在APP_Start檔案夾下建立一個ControllerGroupAttribute特性類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace myFirst.App_Start
{
///
/// Controller描述資訊 ///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ControllerGroupAttribute : Attribute
{ ///
/// 目前Controller所屬子產品 請用中文
public string GroupName { get; private set; }
/// 目前controller用途 請用中文 ///
public string Useage { get; private set; }
/// Controller描述資訊 構造
public ControllerGroupAttribute(string groupName)
{
if (string.IsNullOrEmpty(groupName) || string.IsNullOrEmpty(useage))
{
throw new ArgumentNullException("分組資訊不能為空");
}
GroupName = groupName;
Useage = useage;
}
}
}
參考位址
設定響應類模型
通過ResponseType特性進行設定
格式為: [ResponseType(typeof(ViewModel))]
SwaggerUI中的顯示:
參考位址
修改SwaggerConfig.cs檔案
using System.Web.Http;
using WebActivatorEx;
using leaveSystemAPI;
using Swashbuckle.Application;
using System;
using myFirst.App_Start;
using System.Linq;
using Swashbuckle.Swagger;
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace myFirst
{
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "myFirst");
//顯示api接口注釋
var xmlFile = string.Format(@"{0}\bin\myFirst.xml", System.AppDomain.CurrentDomain.BaseDirectory);
if (System.IO.File.Exists(xmlFile))
{
c.IncludeXmlComments(xmlFile);
}
c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, xmlFile));
//設定分組名字
c.GroupActionsBy(apiDesc =>
apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().Any()?
apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().First().GroupName + " - " +
apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().First().Useage :"暫未設定ControllGroup");
})
.EnableSwaggerUi(c =>
{
c.DocumentTitle("My Swagger UI");
//加載漢化的js檔案
c.InjectJavaScript(System.Reflection.Assembly.GetExecutingAssembly(), "myFirst.swagger-China.js");
});
}
}
}
完成以上修改後啟動項目,在位址欄中加上/swagger
例如: localhost:42361/swagger
即可通路到你的線上文檔了