大摇大摆未加载-无法加载API定义:提取错误未定义

时间:2019-07-02 20:24:58

标签: c# asp.net-mvc swagger-ui

尝试与IIS Express上托管的Web应用程序一起设置设置。 API是使用ASP Net Core构建的。我已按照Microsoft相关帮助页面上有关Swashbuckle和ASP.NET Core的指示进行操作。

到此为止,我已经加载了swagger页面,可以看到我定义的SwaggerDoc正在加载,但是没有API。当前出现以下错误:

  

“未定义提取错误。/swagger/v1/swagger.json”

public class Startup
{

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // services.AddDbContext<TodoContext>(opt =>
        // opt.UseInMemoryDatabase("TodoList"));
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // Register the Swagger generator, defining 1 or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "API WSVAP (WebSmartView)", Version = "v1" });
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
        // specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("./swagger/v1/swagger.json", "My API V1");
            c.RoutePrefix = string.Empty;
        });

        app.UseMvc();
    }
}

17 个答案:

答案 0 :(得分:9)

只需导航到 https://localhost:{PortNo}/swagger/v1/swagger.json 即可获取有关错误消息的更多详细信息。

答案 1 :(得分:3)

我在 .NET 5.0 中也有类似的问题,我通过以下方式解决:

enter image description here

我在控制器上添加了这一行作为属性:

[Consumes("application/json")]

答案 2 :(得分:2)

因此,在进行了大量的故障排除后,基本上可以归结为两点,但是我认为总体上这对将来的其他人可能会有帮助,所以我发布了答案。

首先-如果您遇到上述错误,最好的办法是通过将以下行添加到Configure()方法中来

app.UseDeveloperExceptionPage();

现在,如果您导航到“ swagger / v1 / swagger.json”页面,您应该会看到一些更多信息,这些信息将为您指明有用的方向。

第二-现在对我来说,错误是

  

“使用路径'some_path'和方法'GET'的多次操作”

但是这些API位于依赖库中,因此我无法在定义时应用解决方案。作为一种解决方法,我发现将以下行添加到您的ConfigureServices()方法中解决了该问题

services.AddSwaggerGen(c =>
{
     c.SwaggerDoc("v1", new Info { Title = "API WSVAP (WebSmartView)", Version = "v1" });
     c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); //This line
});

最后-毕竟,我能够生成JSON文件,但仍然无法启动UI。为了使此工作正常,我不得不在Configure()中更改终点

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("./v1/swagger.json", "My API V1"); //originally "./swagger/v1/swagger.json"
});

我不确定为什么需要这样做,尽管可能值得注意的是,Web应用程序的虚拟目录托管在IIS上,这可能会起作用。

希望这对以后的人有帮助。

答案 3 :(得分:2)

我有两个导致相同错误的问题。

  1. 在两个不同的命名空间下,我有两个具有相同名称的类。 Swagger无法在生成swagger文档时调和。要解决此问题,我添加了行options.CustomSchemaIds(x => x.FullName); See explanation here

  2. 我有一个没有[HttpGet]批注的方法。 Swagger需要明确定义HTTP端点。

在加载API之后,我通过在Visual Studio中检查输出来发现这两个问题。

答案 4 :(得分:2)

我一直在使用.Net Core 3.1,并且花了一些时间来找出并理解正在发生的事情。

此问题可能由多种原因引起:

enter image description here

  1. 大刀阔斧的配置错误

  2. 名称相同但名称空间不同的类

  3. 不带有rest属性(Get,Post等)的公共方法

首先,请看下面的链接,以检查您的设置是否正常:

Add Swagger(OpenAPI) API Documentation in ASP.NET Core 3.1

然后

找出问题的一个好技巧是运行应用程序而不使用IISExpress并检查控制台日志。发现生成文档的任何错误都将显示在此处。

在我的情况下,问题在于我有一个公共方法(应该是私有的),没有任何rest属性:

enter image description here

将公开方式更改为私有方式后,我解决了这个问题。

答案 5 :(得分:1)

我有类似的问题,我使用有问题的控制器方法上的Route属性解决了该问题:

[HttpGet, Route("Throw")]
public ActionResult<string> Throw()
{
    _logger.LogInformation("I think I am going to throw up");
    throw new NotSupportedException("For testing unhandled exception logging.");
}

我认为ResolveConflictingActions可能会在地毯下扫清一个真正的问题。

答案 6 :(得分:1)

在努力寻找原因之前,我遇到了相同的错误,我发现我的一个控制器中的API之一没有HTTP动词作为属性,因此我通过将[HttpGet]放在我的API。 因此,这是我的建议,请检查您的API控制器,也许您会忘记与我相同的东西!

看看我的代码,我意识到我应该更改它:

   public async Task<Product> ProductDetail(int id)
    {
        return await _productQueries.GetProductDetail(id);
    } 

对此:

        [Route("ProductDetail")]
        [HttpPost]
        public async Task<Product> ProductDetail(int id)
        {
            return await _productQueries.GetProductDetail(id);
        } 

答案 7 :(得分:0)

对于 ASP.NET Core 3.1,我必须确保动词没有歧义,我通过在 VS2019 中首先运行没有 IIS 的 API 项目发现了这一点(绿色箭头 > 左键单击胡萝卜图标并选择项目名称这会导致在启动时出现一个控制台窗口,以便您可以检查发生的情况并查看错误)。

[HttpGet("MyEndPointA")

然后 Swagger 能够正确生成文档。

答案 8 :(得分:0)

在我的情况下,Swagger 需要 [HttpAction] 与控制器中的所有公共成员。不幸的是,我拼错了构造函数名称,因为它是公开的,所以抛出了这个错误。

答案 9 :(得分:0)

我遇到了同样的问题,所以我使用浏览器上的检查元素检查了它。 “控制台”选项卡显示问题源自的文件 (v1/swagger/json:1)。通过单击打开它显示我在控制器中使用的辅助方法之一是“公共”。将其更改为“私人”解决了我的问题。

这个页面也有很好的提示: https://btrehberi.com/swagger-failed-to-load-api-definition-fetch-error-undefined-hatasi-cozumu/yazilim/

答案 10 :(得分:0)

我一添加 HTTP 属性就忘了在我的控制器中添加 HTTP 属性,它对我来说就像一个魅力。 enter image description here

来源:https://www.benday.com/2020/12/16/webapi-core-swagger-failed-to-load-api-definition-error/

答案 11 :(得分:0)

当这发生在我身上时,我将其追踪到带有下划线的 URL 路径参数,它与 asp 生成器兼容

改变这一点:

/block-content/{machine_name}:

为此

/block-content/{machineName}:

帮我解决了

答案 12 :(得分:0)

将应用服务部署到 Azure 时可能会发生此错误。我已将应用服务重新部署到 Azure,错误消失了。

答案 13 :(得分:0)

我遇到了同样的问题,基本控制器没有用 Http 装饰,删除它就可以了。

答案 14 :(得分:0)

我可以通过打开“网络”标签并查看swagger.json的响应来找到错误

enter image description here

答案 15 :(得分:0)

我在这个问题上只花了两个小时,但原因却完全不同,它与路线或注释无关。我有两个名称相同(但名称空间不同)的类:MyProject.Common.ClassNameMyProject.Api.ClassName。 Swagger / swashbuckle无法分辨两者之间的区别,所以我得到了那个无用的错误。

花了2个小时的反复试验来注释掉控制器和端点,以最终找到3个违反端点的端点。所有3个端点具有不同的路由,不同的(或没有)自定义授权以及不同的方法名称。事实证明,所有3个端点都接受了包含我的类的API版本的参数或返回了一个对象。没有地方使用通用版本。昂首阔步无法分辨他们,然后把自己全部吐了出来。

为什么哦,为什么Swagger或Swashbuckle无法提供实际的错误消息?本来可以节省我几个小时...

答案 16 :(得分:0)

就我而言,Controller类中有2个方法,它们具有相同的注释和URL。 (我们的团队正在使用Entity Framework,ASP.NET和Swagger。)

    [HttpGet("GetMyGreatData/{patientId}")]
    [ValidatePatient]
    public async Task<ActionResult<ServiceResponse<IEnumerable<MyGreatModel>>>> GetMyGreatData(
    [FromRoute] int patientId, int offset = 0, int limit = 0)
    {
        //method details...
    }


    [HttpGet("GetMyGreatData/{patientId}")]
    [ValidatePatient]
    public async Task<ActionResult<ServiceResponse<IEnumerable<MyGreatModel>>>> GetMyGreatData( 
    [FromRoute] int patientId, 
    [FromQuery] DateTimeOffset? startdate = null,
    [FromQuery] DateTimeOffset? endDate = null,
    int offset = 0,
    int limit = 0)
    {
        //method details...
    }

删除一种方法为我解决了这个问题。