You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:08:54