Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6.3.0 System.ArgumentException: Literal sections cannot contain the '?' character. #2385

Open
spaasis opened this issue Mar 24, 2022 · 11 comments · May be fixed by #2473
Open

6.3.0 System.ArgumentException: Literal sections cannot contain the '?' character. #2385

spaasis opened this issue Mar 24, 2022 · 11 comments · May be fixed by #2473
Labels
help-wanted A change up for grabs for contributions from the community

Comments

@spaasis
Copy link

spaasis commented Mar 24, 2022

Hi,

Recently updated from 6.2.1 to 6.3.0 and stuff started breaking.
I'm running an OData controller via aspnet-api-versioning

Any endpoint within an OData controller with manually defined query parameters results in
System.ArgumentException: The literal section 'QuantityUnits?onlyValid=' is invalid. Literal sections cannot contain the '?' character. (Parameter 'routeTemplate')

Controller and endpoint:

namespace WebApi.V1.CodeLists;

[ODataRoutePrefix("QuantityUnits")]
public class QuantityUnitsController : BaseODataController {
    [EnableQuery]
    [ProducesResponseType(typeof(ODataListWrapper<IQueryable<QuantityUnitOutput>>), Status200OK)]
    public async Task<IQueryable<QuantityUnitOutput>> Get(bool onlyValid = true) => ...
}

This works in 6.2.1. In 6.2.3 I observed that the swagger.json generation works, but the endpoint produced has a trailing {, e.g. /api/v1/odata/QuantityUnits{ which of course doesn't really work.

Any idea where to start digging?

Full stack trace:

[14:07:26 INF] Request starting HTTP/2 GET https://localhost:44395/swagger/v1/swagger.json - -
[14:07:26 ERR] An unhandled exception has occurred while executing the request.
System.ArgumentException: The literal section 'QuantityUnits?onlyValid=' is invalid. Literal sections cannot contain the '?' character. (Parameter 'routeTemplate')
 ---> Microsoft.AspNetCore.Routing.Patterns.RoutePatternException: The literal section 'QuantityUnits?onlyValid=' is invalid. Literal sections cannot contain the '?' character.
   at Microsoft.AspNetCore.Routing.Patterns.RoutePatternParser.Parse(String pattern)
   at Microsoft.AspNetCore.Routing.Patterns.RoutePatternFactory.Parse(String pattern)
   at Microsoft.AspNetCore.Routing.Template.TemplateParser.Parse(String routeTemplate)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Routing.Template.TemplateParser.Parse(String routeTemplate)
   at Swashbuckle.AspNetCore.SwaggerGen.ApiDescriptionExtensions.RelativePathSansParameterConstraints(ApiDescription apiDescription)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.<>c.<GeneratePaths>b__6_0(ApiDescription apiDesc)
   at System.Linq.Lookup`2.Create(IEnumerable`1 source, Func`2 keySelector, IEqualityComparer`1 comparer)
   at System.Linq.GroupedEnumerable`2.GetEnumerator()
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Hellang.Middleware.ProblemDetails.ProblemDetailsMiddleware.Invoke(HttpContext context)

@ruapho
Copy link

ruapho commented Mar 28, 2022

Same here. Works in Version 6.2.3 and breaks in 6.3.0.

@Sergey-Terekhin
Copy link

Same story

@spaasis
Copy link
Author

spaasis commented May 23, 2022

Still happens in 6.3.1

@spaasis
Copy link
Author

spaasis commented May 24, 2022

Some more diagnostics and a workaround:

Besides the explicit config in the opening post, the same issue is caused when an OData controller has a PATCH/POST/PUT that takes the parameters from query instead of request body:

    [HttpPatch]
    public async Task<ActionResult> Patch([FromQuery] MyCommand cmd) {

This causes the relative url to have ? and the error is thrown.

I worked around this myself by splitting these write operations to a different, non-odata controller

@spaasis
Copy link
Author

spaasis commented Jul 25, 2022

Still broken in 6.4.0

icnocop added a commit to icnocop/Swashbuckle.AspNetCore that referenced this issue Aug 2, 2022
@seriouz
Copy link

seriouz commented Aug 25, 2022

Still broken! Cannot define a route with [Route("api/test?id={var}")]

@icnocop
Copy link
Contributor

icnocop commented Sep 20, 2022

Work-around:

  1. Download build artifacts from Remove query string parameters when generating OpenApi paths #2473:
    https://ci.appveyor.com/project/domaindrivendev/ahoy/builds/44347663/artifacts

Swashbuckle.AspNetCore.6.4.0-preview-2078.zip

  1. Create/update NuGet.Config and point to local repository:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
      <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
      <add key="Local Swashbuckle.AspNetCore" value="..\..\..\Third Party\Swashbuckle\Swashbuckle.AspNetCore\6.4.0-preview-2078" />
  </packageSources>
</configuration>
  1. Update NuGet package references to use these packages instead.

@icnocop
Copy link
Contributor

icnocop commented Dec 9, 2022

As another work-around, migrate to NSwag.AspNetCore and use the following document processor:

    using System.Collections.Generic;
    using System.Linq;
    using NJsonSchema;
    using NSwag;
    using NSwag.Generation.Processors;
    using NSwag.Generation.Processors.Contexts;

    /// <summary>
    /// Removes query string parameters from paths in the Open API specification document.
    /// </summary>
    /// <seealso cref="NSwag.Generation.Processors.IDocumentProcessor" />
    public class RemoveQueryStringParametersFromPathsDocumentProcessor : IDocumentProcessor
    {
        /// <inheritdoc/>
        public void Process(DocumentProcessorContext context)
        {
            List<string> pathsToFix = new List<string>();

            foreach (var path in context.Document.Paths)
            {
                if (path.Key.Contains('?'))
                {
                    pathsToFix.Add(path.Key);
                }
            }

            foreach (var pathToFix in pathsToFix)
            {
                string key = pathToFix[..pathToFix.IndexOf('?')];
                var pathItem = context.Document.Paths[pathToFix];
                if (context.Document.Paths.ContainsKey(key))
                {
                    context.Document.Paths[key].AddRange(pathItem);
                }
                else
                {
                    context.Document.Paths.Add(key, pathItem);
                }

                context.Document.Paths.Remove(pathToFix);
            }
        }
    }

Usage, in Startup.cs in ConfigureServices:

services.AddOpenApiDocument((settings, serviceProvider) =>
{
    settings.DocumentProcessors.Add(new RemoveQueryStringParametersFromPathsDocumentProcessor());
}

@JLeczycki
Copy link

It still exists in 6.5.0... Any solution for that for shawbuckle package?

Copy link
Contributor

This issue is stale because it has been open for 60 days with no activity. It will be automatically closed in 14 days if no further updates are made.

@github-actions github-actions bot added the stale Stale issues or pull requests label Apr 26, 2024
@martincostello
Copy link
Collaborator

Community contributions to fix this are welcome.

Otherwise this will continue to be an issue as long as this issue is open.

@martincostello martincostello added help-wanted A change up for grabs for contributions from the community and removed stale Stale issues or pull requests labels Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help-wanted A change up for grabs for contributions from the community
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants