如何让Swashbuckle生成的Swagger.json可在线编辑并记录接口结果?
实现Swagger JSON在线编辑与接口结果记录方案
针对你的.NET Framework 4.7 ASP.NET Web API项目,我来一步步帮你实现两个需求:在线编辑Swashbuckle生成的swagger.json,以及记录接口调用结果到JSON文件。
一、实现Swagger JSON的在线编辑功能
默认情况下Swashbuckle是动态生成swagger.json的,我们需要先把这个JSON持久化到文件,再提供编辑和加载修改后版本的能力。
1. 添加Swagger编辑接口
创建一个API控制器来处理swagger.json的读取和保存:
using System.IO; using System.Web.Http; using Swashbuckle.Swagger; namespace Com.Deg.Web.Controllers { public class SwaggerEditorController : ApiController { // 存储修改后的swagger.json的路径 private readonly string _swaggerFilePath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/App_Data"), "swagger-modified.json"); // 获取可编辑的Swagger JSON(不存在则生成初始版本) [HttpGet] [Route("api/SwaggerEditor/GetModifiedSwagger")] public IHttpActionResult GetModifiedSwagger() { if (!File.Exists(_swaggerFilePath)) { // 调用Swashbuckle的原生生成逻辑获取初始文档 var swaggerProvider = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(ISwaggerProvider)) as ISwaggerProvider; var swaggerDoc = swaggerProvider.GetSwagger("v1", null); var initialJson = Newtonsoft.Json.JsonConvert.SerializeObject(swaggerDoc, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(_swaggerFilePath, initialJson); } var jsonContent = File.ReadAllText(_swaggerFilePath); return Content(System.Net.HttpStatusCode.OK, jsonContent, "application/json"); } // 保存修改后的Swagger JSON [HttpPost] [Route("api/SwaggerEditor/SaveModifiedSwagger")] public IHttpActionResult SaveModifiedSwagger([FromBody] string modifiedJson) { try { // 先验证JSON格式合法性 Newtonsoft.Json.Linq.JToken.Parse(modifiedJson); File.WriteAllText(_swaggerFilePath, modifiedJson); return Ok("Swagger文档已成功保存"); } catch (Newtonsoft.Json.JsonException ex) { return BadRequest($"无效的JSON格式:{ex.Message}"); } catch (IOException ex) { return InternalServerError(ex); } } } }
2. 修改SwaggerConfig加载自定义文档
更新SwaggerConfig.cs中的EnableSwaggerUi配置,让Swagger UI加载我们的修改版文档:
.EnableSwaggerUi(c => { // 替换默认的动态生成端点为我们的自定义文档接口 c.SwaggerEndpoint("/api/SwaggerEditor/GetModifiedSwagger", "Deg API (可编辑版)"); })
3. 制作在线编辑页面
添加一个简单的编辑页面(比如在Views目录下创建SwaggerEditor.cshtml),用可视化JSON编辑器来修改内容:
@{ ViewBag.Title = "Swagger 文档编辑器"; } <h2>Swagger JSON 编辑器</h2> <div id="jsoneditor" style="width: 100%; height: 600px; margin-bottom: 15px;"></div> <button id="saveBtn" class="btn btn-primary">保存修改</button> <!-- 引入JSON编辑器依赖 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.4/jsoneditor.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.4/jsoneditor.min.css"> <script> // 初始化编辑器 const editor = new JSONEditor(document.getElementById('jsoneditor'), { mode: 'tree' }); // 加载当前Swagger文档 fetch('/api/SwaggerEditor/GetModifiedSwagger') .then(res => res.json()) .then(data => editor.set(data)); // 保存逻辑 document.getElementById('saveBtn').addEventListener('click', () => { const modifiedJson = JSON.stringify(editor.get(), null, 2); fetch('/api/SwaggerEditor/SaveModifiedSwagger', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(modifiedJson) }) .then(res => res.text()) .then(msg => { alert(msg); // 打开Swagger UI查看修改效果 window.open('/swagger', '_blank'); }) .catch(err => alert(`保存失败:${err.message}`)); }); </script>
二、记录接口调用结果到JSON文件
我们可以通过Web API的Action Filter来拦截接口请求和响应,把结果记录到JSON文件中。
1. 创建日志记录Filter
实现一个自定义Filter来捕获接口执行后的结果:
using System; using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Web.Http.Controllers; using System.Web.Http.Filters; using Newtonsoft.Json; namespace Com.Deg.Web.Filters { public class ApiResultLoggingFilter : ActionFilterAttribute { // 日志文件存储路径 private readonly string _logFilePath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/App_Data"), "api-results.json"); public override async Task OnActionExecutedAsync(HttpActionExecutedContext context, CancellationToken cancellationToken) { // 收集请求基本信息 var requestInfo = new { Method = context.Request.Method.Method, RequestUri = context.Request.RequestUri.ToString(), Timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"), Controller = context.ActionContext.ControllerContext.ControllerDescriptor.ControllerName, Action = context.ActionContext.ActionDescriptor.ActionName }; // 读取响应内容(注意读完后要重置,避免后续流程无法读取) string responseContent = null; if (context.Response?.Content != null) { responseContent = await context.Response.Content.ReadAsStringAsync(); context.Response.Content = new StringContent(responseContent); context.Response.Content.Headers.ContentType = context.Request.Content?.Headers.ContentType; } // 构建日志条目 var logEntry = new { Request = requestInfo, ResponseStatus = context.Response?.StatusCode.ToString(), ResponseContent = responseContent, Exception = context.Exception?.ToString() }; // 追加写入日志文件 var logJson = JsonConvert.SerializeObject(logEntry, Formatting.Indented); using (var writer = new StreamWriter(_logFilePath, append: true)) { await writer.WriteLineAsync(logJson); await writer.WriteLineAsync("---"); // 添加分隔符,方便后续解析 } await base.OnActionExecutedAsync(context, cancellationToken); } } }
2. 注册日志Filter
你可以选择全局注册(所有接口都记录)或者局部注册(仅特定控制器/接口记录):
全局注册(WebApiConfig.cs)
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 添加全局日志Filter config.Filters.Add(new ApiResultLoggingFilter()); // 其他Web API配置 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
局部注册(特定控制器)
[ApiResultLoggingFilter] public class YourApiController : ApiController { // 你的接口方法... }
注意事项
- 权限控制:建议只在开发环境开放Swagger编辑功能,可以通过判断
HttpContext.Current.IsDebuggingEnabled来限制访问。 - 文件读写权限:确保App_Data目录有读写权限,避免保存时出现权限错误。
- 日志文件大小:如果接口调用频繁,建议定期清理日志文件,或者按日期拆分日志。
内容的提问来源于stack exchange,提问作者byte96
相关产品推荐
相关产品推荐

