c# - 当类有循环引用时,Swashbuckle 会抛出 StackOverFlow 异常

标签 c# asp.net-web-api swagger swashbuckle

我有一个如下所示的 Controller ,在 B 类中具有循环引用。

Error

发生这种情况是因为 Swashbuckle 的 jsonserilalizer 设置为 ReferenceLoopHandling = ReferenceLoopHandling.Error 并且我没有找到任何方法来覆盖此设置。

我在 ASP.NET MVC 应用程序中使用 Swashbuckle 5.6.0。

public class IssueController : ApiController
{
    [HttpGet]
    [Route("A")]
    public A Get(A input)
    {
        return new A();
    }
}

public class A
{
    public virtual B prop1 { get; set; }
}

public class B
{
    public virtual B Parent { get; set; }
}

最佳答案

就我而言,事实证明,Stackoverflow 异常不是由 jsonserializer 引起的,而是由上一步引起的(当在 json 序列化之前创建 Swashbuckle 架构时)。圆形引用似乎还不能与 Swashbuckle 一起使用(在 Swashbuckle 中,它似乎已修复)。要解决此问题,您必须复制 HandleFromUriParamsRecurseSave 并将其(与其他过滤器)添加到操作中:

private static SwaggerDocument BuildSwaggerDocument()
        {
            ...
            var operationFilters = new List<IOperationFilter> {
                new HandleFromUriParamsRecurseSave(20),
                ...
            };
        }

在复制的 HandleFromUriParamsRecurseSave 中,只需添加一个 maxrecurselength 属性,该属性适合您的情况,您不应再遇到 StackOverflow 错误:

private void ExtractAndAddQueryParams(
      Schema sourceSchema,
      string sourceQualifier,
      bool? sourceRequired,
      SchemaRegistry schemaRegistry,
      ICollection<Parameter> operationParams)
    {
      foreach (var property in sourceSchema.properties)
      {
        ...
          var recurseCount = sourceQualifier.Count(t => t == '.');
          if (schema.@ref != null && recurseCount < _maxRecurseLength)
          {
            ExtractAndAddQueryParams(schemaRegistry.Definitions[<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8dfeeee5e8e0eca3cdffe8eba3dfe8fde1eceee8" rel="noreferrer noopener nofollow">[email protected]</a>("#/definitions/", "")], sourceQualifier + ToCamelCase(property.Key) + ".", flag, schemaRegistry, operationParams);
          }
          else
          {
            ...
          }
        }
      }
    }

我尝试了进一步的解决方法,但不幸的是没有解决问题,是添加一个堆栈,每次检测到循环时,仅添加一次正确的架构定义(也许有人看到了问题):

    private void ExtractAndAddQueryParams(
      Stack<string> sourceSchemaNames,
      Schema sourceSchema,
      string sourceQualifier,
      bool? sourceRequired,
      SchemaRegistry schemaRegistry,
      ICollection<Parameter> operationParams)
    {
      if (sourceSchemaNames.Count > _maxRecurseLength) {
        return;
      }
      foreach (var property in sourceSchema.properties)
      {
        var schema = property.Value;
        var readOnly = schema.readOnly;
        if (readOnly != true)
        {
          var flag = sourceRequired == true && sourceSchema.required != null && sourceSchema.required.Contains(property.Key);
          var recursionDetected = _disableRecursion && sourceSchemaNames.Contains(schema.@ref);
          if (schema.@ref != null && !recursionDetected)
          {
            sourceSchemaNames.Push(schema.@ref);
            ExtractAndAddQueryParams(sourceSchemaNames, schemaRegistry.Definitions[<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dcafbfb4b9b1bdf29caeb9baf28eb9acb0bdbfb9" rel="noreferrer noopener nofollow">[email protected]</a>("#/definitions/", "")], 
              sourceQualifier + ToCamelCase(property.Key) + ".", flag, schemaRegistry, 
              operationParams);
            sourceSchemaNames.Pop();
          }
          else
          {
...
            if (recursionDetected) {
              partialSchema.type = "object";
              partialSchema.@ref = schema.@ref;
            }
            operationParams.Add(partialSchema);
          }
        }
      }
    }
}

关于c# - 当类有循环引用时,Swashbuckle 会抛出 StackOverFlow 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64485783/

相关文章:

C# 更改私有(private)字段时如何中断?

c# - VS Designer 错误 : GenericArguments[0], 'X' on 'Y' 违反了类型参数 'Z' 的约束

asp.net-web-api - Asp.NET WebApi 基于约定的方法 Url/Route 查询

iis - 许多自托管 SSL owin 服务器

python - 如何使用flaskrestplus设计web的api实现?

java - Swagger codegen RX JAVA + 改造不起作用

c# - 标识符应为 c# 未知原因

c# - 将 DataGridView 导出到 CSV 文本文件

c# - C#MVVM ASP.net API隐式转换错误

c# - 部署后 swagger-ui 返回 500