regomodo
regomodo

Reputation: 754

OpenAPI auto-generated C# server raising UriFormatException

I am trying to get the most basic of OpenAPI server to work as expected. It works as expected with auto-generated python-flask but not with aspnet where exceptions being raised on queries occurs.

What extra steps are required to get the aspnet server to respond correctly to queries?

The YAML is as below:

openapi: 3.0.0
info:
  title: Test API
  version: 0.0.0  
servers:
  - url: http://localhost:{port}
    description: Local server
    variables:
      port:
        default: "8092"    
paths:
  /things:
    get:
      summary: Return a list of Things
      responses:
        '200':
          description: A JSON array of Things
          content:
            application/json:
              schema: 
                type: array
                items: 
                  $ref: "#/components/schemas/Thing" 
components:
  schemas:
    Thing:
      properties:
        id:
          type: integer
        name:
          type: string

In order to get the server to run, the auto-generated launchSettings.json has to be modified from:

...
    "web": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
...

to:

...
    "web": {
      "commandName": "Project",
      "launchBrowser": false,
      "launchUrl": "swagger",
      "applicationUrl": "http://localhost:8092",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
...

The console suggests that the server is running ok

info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
      User profile is available. Using 'C:\Users\jonathan.noble\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
Hosting environment: Development
Content root path: D:\aspnetcore-server-generated\src\IO.Swagger
Now listening on: http://localhost:8092
Application started. Press Ctrl+C to shut down.

However, when a query is made viahttp://localhost:8092/things (this is what the swagger editor suggests to use) the server throws an exception with

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:8092/things
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HM46UOD2UM1E", Request id "0HM46UOD2UM1E:00000001": An unhandled exception was thrown by the application.
System.UriFormatException: Invalid URI: The URI is empty.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString)
   at IO.Swagger.Startup.<ConfigureServices>b__5_2(SwaggerGenOptions c) in D:\aspnetcore-server-generated\src\IO.Swagger\Startup.cs:line 73
   at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
...

Upvotes: 0

Views: 888

Answers (2)

villapx
villapx

Reputation: 1883

Using swagger-codegen-cli version 3.0.27, I experienced the same bug (I'm also just generating the most basic of API servers). It turns out that the generator generates code that tries to instantiate the TermsOfService Uri object with an empty string in Startup.ConfigureServices():

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v0", new OpenApiInfo
    {
        Version = "v0",
        Title = "Test API Spec",
        Description = "Test API Spec (ASP.NET Core 3.1)",
        Contact = new OpenApiContact()
        {
            Name = "Swagger Codegen Contributors",
            Url = new Uri("https://github.com/swagger-api/swagger-codegen"),
            Email = ""
        },
        TermsOfService = new Uri("")    // ********** right here **********
    });
    c.CustomSchemaIds(type => type.FullName);
    string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
    c.IncludeXmlComments(xmlPath);

    // Include DataAnnotation attributes on Controller Action parameters as Swagger validation rules (e.g required, pattern, ..)
    // Use [ValidateModelState] on Actions to actually validate it in C# as well!
    //c.OperationFilter<GeneratePathParamsValidationFilter>();
});

I just deleted the TermsOfService field entirely, and so the error stopped being thrown.

Upvotes: 0

regomodo
regomodo

Reputation: 754

By looking at the differences between the auto-generated code and the sample projects at aspnet-core I found a single line of code that was causing the exception.

In Program.cs an auto-generated bit of code needs to be removed

c.OperationFilter<GeneratePathParamsValidationFilter>();

I'm sure it's there for a reason but it's causing the basic application to fail.

Upvotes: 0

Related Questions