在 asp .net CORE / MVC 6 应用程序中设置 Swagger 时出现 500 错误

500 Error when setting up Swagger in asp .net CORE / MVC 6 app

我正在尝试在新的 asp .net CORE / MVC 6 项目中设置基本的 swagger API 文档,并从 swagger UI 收到 500 错误: 500 : http://localhost:4405/swagger/v1/swagger.json

我的启动程序 class 中包含以下代码:

using Swashbuckle.SwaggerGen;
using Swashbuckle.SwaggerGen.XmlComments;
using Swashbuckle.Application;
....
public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddSwaggerGen();
  services.ConfigureSwaggerDocument(options =>
  {
    options.SingleApiVersion(new Info
    {
        Version = "v1",
        Title = "Blog Test Api",
        Description = "A test API for this blogpost"
    });
  });
}

然后在配置下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
....
  app.UseSwaggerGen();
  app.UseSwaggerUi();
....
}

当我构建和运行项目时,当我转到swagger/UI/index.html时会出现UI,但显示上面的500错误。当我转到 swagger/v1/swagger.json link 时,控制台出现以下 500 错误: Failed to load resource: the server responded with a status of 500 (Internal Server Error)

有什么方法可以找出 500 的根本原因,或者启用任何额外的 swagger 调试来找出它抛出此错误的原因?根据我看过的一些教程,基本实现只需要我在启动时拥有的内容。如果我可以提供任何其他信息,请告诉我。

编辑:这是针对 rc1 的,可能与当前发布的新 netcore 1.0 无关 (6/29/2016)

看看这个项目。 https://github.com/domaindrivendev/Ahoy/tree/master/test/WebSites/Basic

这个 repo 来自 Swashbuckle 的所有者,是一个基本的 ASP.NET 5 示例应用程序,这可以帮助您正确配置您的中间件(并注意它们的顺序,这很重要,例如,使用“app.UseSwaggerGen();app.UseSwaggerUi(); 在 app.UseMvc();)

之后

要在您的应用程序中启用日志记录,请查看: https://docs.asp.net/en/latest/fundamentals/logging.html?highlight=logging (日志将在 "wwwroot" 文件夹

中生成

Swagger 的设置因版本而异。此答案适用于 Swashbuckle 6.0.0-beta9 和 Asp.Net Core 1.0。在Startup.cs的ConfigureServices方法里面,需要添加-

 services.AddSwaggerGen(c =>
    {
      c.SingleApiVersion(new Info
      {
        Version = "v1",
        Title = "My Awesome Api",
        Description = "A sample API for prototyping.",
        TermsOfService = "Some terms ..."
      });
    });

然后在Configure方法中你必须添加-

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseMvc();
    app.UseSwaggerGen();
    app.UseSwaggerUi();
}

请确保您在 Startup.cs -

中引用

使用Swashbuckle.SwaggerGen.Generator;

我的 project.json 文件看起来像 -

"dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-*",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "Swashbuckle": "6.0.0-beta9"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "frameworks": {
    "net452": { }
  },
  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true,
    "xmlDoc": false
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

最初我也遇到了 500 错误。在堆栈跟踪的深处,它说: System.NotSupportedException:路径“api/hotels”的无界 HTTP 动词。您是否缺少 HttpMethodAttribute?

原来我缺少一个 api 方法的 HttpGet 属性:

[Microsoft.AspNetCore.Mvc.HttpGet]

此外,如果我可以补充一点,当您在控制器的根级别路由时,swagger 设置不喜欢它。例如:

不要这样做:

[Produces("application/json")]
[Route("/v1/myController")]
[Authorize]
public class myController
{
    [SwaggerResponse((int)System.Net.HttpStatusCode.OK, Type = typeof(RestOkResponse<Response>))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.InternalServerError, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.BadRequest, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.Forbidden, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.NotFound)]
    [HttpPost]
    [Authorize()]
    public async Task<IActionResult> Create([FromBody] MyObject myObject)
    {
        return Ok();
    }
}

这样做:

[Produces("application/json")]
[Authorize]
public class myController
{
    [SwaggerResponse((int)System.Net.HttpStatusCode.OK, Type = typeof(RestOkResponse<Response>))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.InternalServerError, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.BadRequest, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.Forbidden, Type = typeof(RestErrorResponse))]
    [SwaggerResponse((int)System.Net.HttpStatusCode.NotFound)]
    [HttpPost("/v1/myController")]
    [Authorize()]
    public async Task<IActionResult> Create([FromBody] MyObject myObject)
    {
        return Ok();
    }
}

我花了一段时间才弄清楚我收到内部服务器错误的原因是这个路由问题。希望这对某人有帮助!

首先,您可以通过在 Configure() 上添加 app.UseDeveloperExceptionPage(); 来启用开发人员异常页面,以便更好地了解根本原因。看看here

在我的例子中,问题是我还必须安装 Microsoft.AspNetCore.StaticFiles nuget 才能使 Swagger 工作。

也尝试 uninstall/reinstall Swashbuckle.AspNetCore nuget。

当我的一个函数被标记为 public 时出现此错误,但这并不是一个可以直接调用的 Web 服务。

将函数更改为 private 使错误消失。

或者,在 public 函数之前,您可以放置​​ [NonAction] 命令,告诉 Swagger 忽略它。

[NonAction]
public async Task<IActionResult> SomeEvent(string id)
{ 
   ...
}

(我希望 Swagger 实际上会报告导致此问题的函数的 name,而不是仅仅抱怨它无法再找到“ ../swagger/v1/swagger.json" 文件...这不是特别有用。)

如果有人想知道 Swagger 堆栈跟踪中的确切错误,请请求 URL:

<your-app-url>/swagger/v1/swagger.json

或者,从浏览器开发工具控制台单击 swagger.json link:

这将在您的 IDE 输出中显示错误:

当我添加参数 Version 时,它起作用了

services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        });

可能很明显,但是除了缺少 HttpGetHttpPost 属性外,不要忘记区分 post 方法。

您可能有 2 个不同的方法(具有不同的名称)标记为 HttpPost,这也会导致此类问题。记得在属性中指定方法名:[HttpPost("update")].

查看异常来源

  • 打开chrome浏览器
  • 打开开发者工具
  • 在控制台选项卡中查看例外情况
  • 修复它。

也有这个问题。在我的例子中,它是由同一控制器中的两个端点引起的,它们具有相同的路由和方法名称(但参数类型不同)。当然,后来很明显这可能是不好的做法,所以我更改了端点名称,一切都很好。

在某些情况下,控制器 的路由器是重复的。查看最后修改的控制器

我收到此错误是因为在 STARTUP.CS 中我没有将版本名称放入 SwaggerDoc 参数中:

错误 => c.SwaggerDoc("", blablabla

工作 => c.SwaggerDoc("v1",blablabla

然后,现在都ok啦!

services.AddSwaggerGen(c => 
    {
c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info {Title = "PME SERVICES", Version = "v1"});
            });

我 运行 今天在 .Net Core 2.2 Web Api 项目中配置 Swagger 这个问题。我开始沿着@Popa Andrei 上面提到的路径开始,在我的项目中包含 Microsoft.AspNetCore.StaticFiles 依赖项,因为我认为这很可能是罪魁祸首。尽管它最终对我有用,但它变成了链接依赖项的兔子洞。

然后我意识到,在 Startup 中的 ConfigureServices 方法中,我有 services.AddMvcCore(...),它只是给你简单的骨头,你可以根据需要添加依赖项。当我将其更改为 services.AddMvc(...) 时,它开始工作而无需手动添加 Microsoft.AspNetCore.StaticFiles.

所需的所有依赖项

这并不意味着您不能继续使用 services.AddMvcCore(...) 然后添加所有必要的依赖项。你可以,而且它会起作用。

采用 services.AddMvc(...) 方法更容易完成。

希望对某人有所帮助。

确保我的 swagger 版本彼此对齐解决了我的问题。因为我开始了一个新项目,所以我将我的 api 版本设置为 v0.1

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v0.1", new Info { Title = "Tinroll API", Version = "v0.1" });
});

但离开了我的招摇 url 成为 v1。

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Tinroll API v0.1");
    c.RoutePrefix = string.Empty;
});

我将我的版本更新为 /swagger/v0.1/swagger.json 而不是 v1,并且 Swagger 按预期工作。

由于我没有在此处看到对我有用的解决方案,因此我将在正在进行的讨论中贡献一个。在我的例子中,Route 属性是在函数级别(不是控制器级别)与 HttpPost/HttpGet 分开设置的。

不正确:

[HttpPost]

[Route("RequestItem/{itemId}")]

正确:

[HttpPost("RequestItem/{itemId}")]

此外,对于 return.

的成功请求,Swagger 似乎期望 Ok(object) 结果而不是 StatusCode(object) 结果

对我来说,这是因为有两个 class 类型具有相同的名称但具有不同的名称空间,它们在不同的控制器中用作两个不同操作的 return 类型!

当我更改其中一个的名字时,问题就解决了!

对我来说,问题是由于 OData。如果我只是注释掉我的 services.AddOData();我没有收到任何错误。just comment out the services.AddOData();

我今天遇到了这个问题,原因是我的控制器 API 上的一些方法丢失了 [HttpGet]:

异常(在堆栈跟踪中)向我展示了问题所在 您还可以像这样检查 Visual Studio 中的输出 window 中的异常(在我的例子中它向我显示):

有同样的问题,错误消息帮助我确定了根本原因:

{
  "error": "Conflicting method/path combination \"POST api/calls\" for actions - SMSApi_v2.Controllers.CallController.CreateCall (SMSApi_v2),SMSApi_v2.Controllers.CallController.CreateCalls (SMSApi_v2). Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround"
}

根源是这些代码行:

    **[HttpPost("calls")]**
    public IActionResult CreateCall([FromBody]Call call)
    {
        repository.Create(call);
        return Ok(call);
    }

    **[HttpPost("calls")]**
    public IActionResult CreateCalls([FromBody] string xmlFile)
    {
        var calls = xmlProcessor.DeserializeTo<List<Call>>(xmlFile);
        if (!calls.Any())
            return BadRequest("Deserializing was not done correctly.");

        repository.Create(calls);
        return Ok(calls);
    }

即使方法的签名不同,两个 API 动词具有相同的路由,这会产生错误。

我在 ASP.NET 样板中遇到同样的错误。我搜索了很多,发现我的代码有问题。我使用同名的两个 DTO 对象,但位于不同的命名空间。

例如第一个 DTO 对象如下所示:

namespaces Test{
    public class TestDto
    {
        public int Id{get;set;}
    }
}

第二个 DTO 对象如下所示:

namespaces Test_2{
    public class TestDto
    {
        public int Id{get;set;}
    }
}

我更改了Test_2.TestDto的名字,之后问题确实解决了。

如果您使用 .Net Core 5 默认启用的 Swagger,它需要了解您的方法。通常,您不需要添加 [HttpGet] 属性,因为它是您方法的默认 HttpMethod,但 swagger 需要该信息来生成代码文档。

所以在我的方法上方添加 [HttpGet] 解决了我的问题。

在我的例子中,一个模型与另一个模型同名,我修改了名称

如果您无法加载并查看控制台中的 swagger.json,请查看此处。

Swagger 很难协商名称空间之间的差异。在构建预期用于 api 调用的对象时,它将通过每个定义的 class 进行索引。如果有两个 class 共享一个 class 名称,它将无法处理 swagger.json 文件。

.Net 将正确处理但 Swagger 不会正确处理的两个 classes 的示例。

namespace MyCompany.PaymentProcessor.DTO
{

    public class Payment
    {
      //dto content
    }
}

namespace MyCompany.CbData
{

    public class Payment
    {
       //couch base data
    }
}

将被 .Net 正确处理,但无法被 swagger 解析。

在我的例子中,我在你的 API 控制器中存在的路由属性中缺少一个动作。

像这样:

[Route("api/[controller]/[action]")]

之前我有:

[Route("api/[controller]")]

[Route("api/[controller]")]时出错,因为swagger不知道如何分离API 方法在你的路由属性中没有动作。

  1. 在 api 操作之上添加 [HttpGet] 或 [HttpPost]。

  2. 在 api 操作之上添加 [Reout("YourApiActionName")]

    或在您的控制器 class.

    之上添加 [Route("[controller]/[action]")]