onefootswill
onefootswill

Reputation: 4077

Swagger is Adding Placeholder Text to the Url in Requests sent by the Try It Out Feature

I'm using Swagger and SwaggerUi (via the Swashbuckle.AspNetCore Nuget package) for my WebAPI project.

The problem that I am having is that the UI is not forming the request properly for the Try It Out feature. For example, my API has a nullable long in the method signature at the server. That parameter is called modifiedSince.

When I click execute, without a value in the modifiedSince text input, the following Url is hit https://localhost:44348/v1/Complication/%7BmodifiedSince%7D

It is picking up the Placeholder text and including that in the URL (inside html-encoded curly braces).

On another endpoint, I have two parameters and the URL is meant to look like this: https://localhost:44348/v1/Logbook/37193/Entry/2121321

But when I click the Try It Out button, SwaggerUi sends https://localhost:44348/v1/Logbook/37193/Entry/%7BentryId%7D?entryId=2121321 and as a result, a null value comes into my server's method for the entryId parameter.

Again, the placeholder of the relevant text input is being added to the url.

I upgraded from 2.5.0 to 3.0.0 in a bid to fix the issue. But it is still occurring.

An example of a Controller action which the Swagger API is hitting is:

/// <summary>
/// Logbooks of user.
/// </summary>
/// <param name="modifiedSince"></param>
/// <returns></returns>
/// <response code="200">Logbooks assigned to the user</response>
/// <response code="204">No logbooks assigned to the user</response>
/// <response code="400">Error state. Error message included in payload.</response>        
/// <response code="403">Authentication required.</response>        
[HttpGet]
[Route("[action]/{modifiedSince?}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ApiResponse<IEnumerable<LogbookDto>>), 200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(ApiResponse<string>), 400)]
[ProducesResponseType(typeof(ApiResponse<string>), 403)]
public async Task<IActionResult> Logbook(long? modifiedSince)
{
    var logbookDtos = default(IEnumerable<LogbookDto>);

    if (await AuthorizeAsync(User, IdentityConstants.PolicyNames.RacsUser) &&
        await Execute(async () => logbookDtos = await _mediator.Send(
            new GetLogbooksQuery
            {
                UserId = _currentUser.UserId
                //LastConfigChange = NULL
            }))
            )
    {
        if (logbookDtos.Any())
            return Ok(new ApiResponse<IEnumerable<LogbookDto>> { Data = logbookDtos, Outcome = new OperationOutcome { Error = false, Message = "" } });

        return NoContent();
    }

    return ErrorResponse(new ApiResponse<string> { Data = Errors, Outcome = new OperationOutcome { Error = true, Message = "" } });
}

Here is a pic from Chrome dev tools to depict what is happening:

enter image description here

Does anyone know what's going on? Have I missed a config somewhere?

Upvotes: 4

Views: 2878

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17594

Expanding from the comments:

If it works when you remove the nullable that points to a bug in swashbuckle, you should report it:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/new

The only thing that I'm a bit fuzzy is that from a JSON Schema perspective a nullable does not necessarily imply not required...
You can have field required and allow null as a value

There are some things that C# does that do not directly translate to something in swagger, my recommendation remove the nullable, maybe instead you can use a default value, something like:
public async Task<IActionResult> Logbook(long modifiedSince = -1)

And handle the default case in code

Upvotes: 2

Related Questions