.Net WebApi— SwaggerUI配置
创始人
2024-05-02 16:00:53
0

最近新公司用了特别老的技术【Web 服务 .asmx文件 做WebService服务】,而WebApi早就流行四五年了;
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
实在太过于简陋,关键其他系统对接的同事,经常说对接不上,如果接口过多确实不方便接口管理,所以最终决定重新搭建wepai 方便后续接口开发和管理。

一、创建ASP.NET WEB 应用程序 选择空的模板
二、在项目中添加文件夹 App_Start (wepapi 启动项配置文件)
三、在项目中添加文件夹 Controller (用来编写Controller 也就接口)
四、在项目中添加文件夹 Script (用来做文档SwaggerUI的汉化版处理)
在这里插入图片描述

App_Start文件夹
配置 WebApiConfig

using FIS.WebService.App_Start;
using Newtonsoft.Json.Converters;
using Swashbuckle.Application;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;namespace FIS.WebService
{public static class WebApiConfig{public static void Register(HttpConfiguration config){config.MapHttpAttributeRoutes();//路由:匹配到actionconfig.Routes.MapHttpRoute(name: "FisApi",routeTemplate: "{controller}/{action}",defaults: new { id = RouteParameter.Optional });config.Routes.MapHttpRoute(name: "swagger_root",routeTemplate: "",defaults: null,constraints: null,handler: new RedirectHandler((message => message.RequestUri.ToString()), "swagger"));//移除XML格式,采用Json进行数据交互config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();//处理DateTime类型序列化后含有T的问题config.Formatters.JsonFormatter.SerializerSettings.Converters.Insert(0, new IsoDateTimeConverter());//config.Filters.Add(new ModeActionFilter());//添加全局异常处理器//config.Filters.Add(new MyAttribute());}}
}

添加 SwaggerConfig

using System.Web.Http;
using WebActivatorEx;
using FIS.WebService;
using Swashbuckle.Application;
using FIS.WebService.App_Start;
using Swashbuckle.Swagger;
using System.Linq;[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]namespace FIS.WebService
{public class SwaggerConfig{public static void Register(){var thisAssembly = typeof(SwaggerConfig).Assembly;GlobalConfiguration.Configuration.EnableSwagger(c =>{c.SingleApiVersion("v1", "Fis WebApi");//显示api接口注释 var xmlFile = string.Format(@"{0}\bin\FIS.WebService.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().Any() ?apiDesc.GetControllerAndActionAttributes().First().GroupName + " - " +apiDesc.GetControllerAndActionAttributes().First().Useage : "暂未设置ControllGroup");}).EnableSwaggerUi(c =>{c.DocumentTitle("Swagger UI");//加载汉化的js文件c.InjectJavaScript(System.Reflection.Assembly.GetExecutingAssembly(), "FIS.WebService.Script.swagger.js");});}}
}

显示swagger控制器的描述

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 FIS.WebService.App_Start
{/// /// 显示swagger控制器的描述/// public class SwaggerControllerDescProvider : ISwaggerProvider{private readonly ISwaggerProvider _swaggerProvider;private static ConcurrentDictionary _cache = new ConcurrentDictionary();private readonly string _xml;/// /// /// /// /// xml文档路径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 { { "ControllerDesc", GetControllerDesc() } };_cache.TryAdd(cacheKey, srcDoc);}return srcDoc;}/// /// 从API文档中读取控制器描述/// /// 所有控制器描述public ConcurrentDictionary GetControllerDesc(){string xmlpath = _xml;ConcurrentDictionary controllerDescDict = new ConcurrentDictionary();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;}}
}

Controller描述信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;namespace FIS.WebService.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描述信息 构造/// /// 模块名称/// 当前controller用途public ControllerGroupAttribute(string groupName, string useage){if (string.IsNullOrEmpty(groupName) || string.IsNullOrEmpty(useage)){throw new ArgumentNullException("groupName||useage");}GroupName = groupName;Useage = useage;}}
}

红框类的是配置文件,其他的是自定义过滤器
在这里插入图片描述Controller 文件夹
添加Controller控制器

using FIS.DAL;
using FIS.Model;
using FIS.WebService.App_Start;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;namespace FIS.WebService.Controller
{[ControllerGroup(groupName: "Process", useage: "工序")]public class ProcessController : ApiController{/* body 获取  string tokenString = HttpContext.Current.Request.Form.Get("tokendata");[ActionName("GetAllPerson")]   指定action[AcceptVerbs("GET", "POST")]   即支持get也支持post[HttpPost]                     post[HttpGet]                      get[NonAction]                    不被外部应用程序调用[Route("api/[controller]")]    指定路由[AllowAnonymous]               所有访问[MyAttribute.MyException]      自定义错误日志过滤器*//// /// 成品出货/// /// [ActionName("SynProductShipment")][HttpPost]public string SynProductShipment(){MessageObj message = new MessageObj();try{string pamet = Request();List productShipments = JsonConvert.DeserializeObject>(pamet.Trim());if (new ProductShipmentDAO().SynProductShipment(productShipments)){message.Status = 1;message.ReturnMessage = "提交成功";}}catch (Exception ex){message.Status = 0;message.ReturnMessage = $"FIS系统内部错误:{ex.Message.ToString()}";}return JsonConvert.SerializeObject(message);}/// /// 获取所有工序/// /// [ActionName("GetAllProces")][AcceptVerbs("GET", "POST")]public string GetAllProces(){return JsonConvert.SerializeObject(new ProcessFlowDAO().GetProcessName());}/// /// 测试验证参数/// /// /// [ModeActionFilter][HttpPost]public string Test([FromBody] List entity){return "成功!";}[NonAction]public string Request(){string pamet = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString(), Encoding.UTF8);if (string.IsNullOrEmpty(pamet)){pamet = HttpContext.Current.Request["inParamJson"];}if (string.IsNullOrEmpty(pamet)){pamet = HttpContext.Current.Request["parm"];}if (string.IsNullOrEmpty(pamet)){Stream reqStream = HttpContext.Current.Request.InputStream;reqStream.Seek(0, SeekOrigin.Begin);byte[] buffer = new byte[(int)reqStream.Length];reqStream.Read(buffer, 0, (int)reqStream.Length);string json = string.Empty;foreach (char a in buffer) { json = json + a.ToString(); }pamet = HttpUtility.UrlDecode(json.ToString(), Encoding.UTF8);}return pamet;}}
}

Script 文件夹
配置SwaggerUI汉化

'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('
  • ' + strSummary + '
  • ');}} 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(); });

    最后添加全局配置Global文件

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;namespace FIS.WebService
    {public class Global : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();GlobalConfiguration.Configure(WebApiConfig.Register);//取消xmlGlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();}protected void Session_Start(object sender, EventArgs e){}protected void Application_BeginRequest(object sender, EventArgs e){}protected void Application_AuthenticateRequest(object sender, EventArgs e){}protected void Application_Error(object sender, EventArgs e){}protected void Session_End(object sender, EventArgs e){}protected void Application_End(object sender, EventArgs e){}}
    }
    

    运行效果
    在这里插入图片描述

    相关内容

    热门资讯

    监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
    Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
    protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
    在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
    【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
    Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
    educoder数据结构与算法...                                                   ...
    MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
    修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
    MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...