.NET Framework 4.7.2 Web API基础框架搭建指南

Ctrl+Z侠 2024-07-27 08:03:01 阅读 67

一、技术概览

本项目集成了以下关键技术,以提升Web API的可用性、安全性和维护性

Swagger接口文档:利用Swagger工具自动生成和维护API文档,为开发者提供清晰的接口定义和测试环境。

Log4Net错误日志统计:通过集成Log4Net日志框架,实现对系统运行时错误的记录与统计,便于问题的快速定位和解决。

Token令牌授权认证:采用Token-based身份验证机制,确保API调用的安全性和用户操作的合法性。

接口防刷机制:部署接口防刷策略,保护API免受恶意攻击和滥用,维护服务的稳定性。

二、配置Swagger接口文档

转载文章:https://blog.csdn.net/suxuelian/article/details/133626818

安装Swagger包

在NuGet包管理器中搜索“Swashbuckle”。请确保选择适合您项目的包版本。对于.NET Core API项目,请安装“Swashbuckle.AspNetCore”。

配置Swagger文档

打开项目中的<code>App_Start文件夹,定位到SwaggerConfig.cs配置文件。

修改配置以自定义Swagger文档的显示信息,例如设置文档的标题和描述。以下是配置文件的示例代码:

using System.Web.Http;

using WebActivatorEx;

using HRflag.WebAPI;

using Swashbuckle.Application;

[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

namespace HRflag.WebAPI

{

/// <summary>

/// Swagger配置文件

/// </summary>

public class SwaggerConfig

{

public static void Register()

{

var thisAssembly = typeof(SwaggerConfig).Assembly;

GlobalConfiguration.Configuration

.EnableSwagger(c =>

{

c.SingleApiVersion("v1", "在线API文档");

})

.EnableSwaggerUi(c =>

{

});

}

}

}

现在直接运行项目,在服务地址后加上\swagger就可以显示所有接口文档了

3. 生成XML注释文件

在Visual Studio中,右键点击您的主项目。

选择“属性”,在打开的项目属性窗口中找到“生成”选项卡。

勾选“XML文档文件”复选框以启用XML注释文件的生成,并指定或确认文件的输出路径。

保存更改。

打开SwaggerConfig.cs文件,进行如下配置以启用XML注释文件的使用:

//WebApi项目的xml注释文档

var apiXml = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin\\HRflag.WebAPI.xml"); //也可以直接复制完整路径(不建议)

c.IncludeXmlComments(apiXml);

对于每个需要添加XML注释的项目,重复上述步骤,并确保Swagger配置中的XML注释文件路径正确无误。

完整代码如下:

using System;

using System.IO;

using System.Web.Http;

using WebActivatorEx;

using HRflag.WebAPI;

using Swashbuckle.Application;

[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

namespace HRflag.WebAPI

{

/// <summary>

/// Swagger配置文件

/// </summary>

public class SwaggerConfig

{

public static void Register()

{

var thisAssembly = typeof(SwaggerConfig).Assembly;

GlobalConfiguration.Configuration

.EnableSwagger(c =>

{

c.SingleApiVersion("v1", "API文档");

//WebApi项目的xml注释文档

var apiXml = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin\\HRflag.WebAPI.xml"); //也可以直接复制完整路径(不建议)

c.IncludeXmlComments(apiXml);

})

.EnableSwaggerUi(c =>

{

});

}

}

}

启动Web API项目后,通过在服务地址后添加/swagger访问Swagger UI,即可查看API文档,注意,默认界面为英文,如需中文界面,需进行相应的汉化配置。

4. 汉化Swagger UI

在NuGet程序包管理器中搜索并安装“Swagger.Net”和“Swagger.Net.UI”包。

安装完成后,注释掉App_Start文件夹中的SwaggerNet类中的assembly 如下:

using Swagger.Net;

using System;

using System.IO;

using System.Web;

using System.Web.Http;

using System.Web.Http.Description;

using System.Web.Routing;

//[assembly: WebActivator.PreApplicationStartMethod(typeof(HRflag.WebAPI.App_Start.SwaggerNet), "PreStart")]

//[assembly: WebActivator.PostApplicationStartMethod(typeof(HRflag.WebAPI.App_Start.SwaggerNet), "PostStart")]

namespace HRflag.WebAPI.App_Start

{

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/HRflag.WebAPI.XML")));

}

catch (FileNotFoundException)

{

throw new Exception("Please enable \"XML documentation file\" in project properties with default (bin\\HRflag.WebAPI.XML) value or edit value in App_Start\\SwaggerNet.cs");

}

}

}

}

创建一个“SwaggerControllerDescProvider”类,用于对swagger文档中的内容进行汉化处理。

/// <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>code>

/// <param name="xml">xml文档路径</param>code>

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;

}

}

在SwaggerUI文件夹中,创建一个swagger_lang.js的js,用于对swagger进行汉化处理(注:这个文件必须添加,否则汉化将失败)swagger_lang.js 文件中的js内容如下:

/// <summary>

/// 中文转换

/// </summary>

var SwaggerTranslator = (function () {

//定时执行检测是否转换成中文,最多执行500次 即500*50/1000=25s

var iexcute = 0,

//中文语言包

_words = {

"Warning: Deprecated": "警告:已过时",

"Implementation Notes": "实现备注",

"Response Class": "响应类",

"Status": "状态",

"Parameters": "参数",

"Parameter": "参数",

"Value": "值",

"Description": "描述",

"Parameter Typ



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。