Skip to content

Composite key route template parsing error #500

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

Closed
maelstraggiotti opened this issue May 10, 2019 · 2 comments
Closed

Composite key route template parsing error #500

maelstraggiotti opened this issue May 10, 2019 · 2 comments
Assignees

Comments

@maelstraggiotti
Copy link

Hello,

I encounter an error when executing routeBuilder.MapVersionedODataRoutes upon app startup, even with a minimal setup. The parsing of a particular composite key route template fails.

The exact same route without versioning works. The issue is reproductible using the attached project. WebApplication1.zip

Model

public class Parent
{
	[Key]
	public int First { get; set; }

	[Key]
	public int Second { get; set; }
}

Controller method

[EnableQuery]
public IActionResult Get(
	[FromODataUri] int keyFirst,
	[FromODataUri] int keySecond)
{
	return Ok(new[]
	{
		new Parent()
	});
}

Libs
Microsoft.AspNetCore.OData.Versionning 3.1.0
Asp.Net Core 2.1.7 on .net framework 4.6.1

Error

Microsoft.OData.ODataException: ')' or ',' expected at position 11 in '({keyFirst}{keySecond})'.
   à Microsoft.OData.UriParser.FunctionCallParser.ParseArgumentListOrEntityKeyList(Action restoreAction) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\FunctionCallParser.cs:ligne 153
   à Microsoft.OData.UriParser.SegmentArgumentParser.TryParseFromUri(String text, SegmentArgumentParser& instance, Boolean enableUriTemplateParsing) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\SegmentArgumentParser.cs:ligne 280
   à Microsoft.OData.UriParser.SegmentArgumentParser.TryParseKeysFromUri(String text, SegmentArgumentParser& instance, Boolean enableUriTemplateParsing) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\SegmentArgumentParser.cs:ligne 153
   à Microsoft.OData.UriParser.SegmentKeyHandler.TryCreateKeySegmentFromParentheses(ODataPathSegment previous, KeySegment previousKeySegment, String parenthesisExpression, ODataUriResolver resolver, ODataPathSegment& keySegment, Boolean enableUriTemplateParsing) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\SegmentKeyHandler.cs:ligne 44
   à Microsoft.OData.UriParser.ODataPathParser.TryBindKeyFromParentheses(String parenthesesSection) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\ODataPathParser.cs:ligne 698
   à Microsoft.OData.UriParser.ODataPathParser.TryCreateSegmentForNavigationSource(String identifier, String parenthesisExpression) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\ODataPathParser.cs:ligne 937
   à Microsoft.OData.UriParser.ODataPathParser.CreateFirstSegment(String segmentText) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\ODataPathParser.cs:ligne 898
   à Microsoft.OData.UriParser.ODataPathParser.ParsePath(ICollection`1 segments) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\ODataPathParser.cs:ligne 132
   à Microsoft.OData.UriParser.ODataPathFactory.BindPath(ICollection`1 segments, ODataUriParserConfiguration configuration) dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\Parsers\ODataPathFactory.cs:ligne 23
   à Microsoft.OData.UriParser.ODataUriParser.ParsePathImplementation() dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:ligne 503
   à Microsoft.OData.UriParser.ODataUriParser.Initialize() dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:ligne 522
   à Microsoft.OData.UriParser.ODataUriParser.ParsePath() dans C:\projects\odata.net\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:ligne 259
   à Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.Parse(String serviceRoot, String odataPath, IServiceProvider requestContainer, Boolean template) dans C:\projects\WebApi\src\Microsoft.AspNet.OData.Shared\Routing\DefaultODataPathHandler.cs:ligne 143
   à Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.ParseTemplate(String odataPathTemplate, IServiceProvider requestContainer) dans C:\projects\WebApi\src\Microsoft.AspNet.OData.Shared\Routing\DefaultODataPathHandler.cs:ligne 76
   à Microsoft.AspNet.OData.Routing.ActionParameterContext..ctor(ODataRouteBuilder routeBuilder, ODataRouteBuilderContext routeContext)
   à Microsoft.AspNet.OData.Routing.ODataRouteBindingInfoConvention.UpdateBindingInfo(ControllerActionDescriptor action, ODataRouteMapping mapping, ICollection`1 routeInfos)
   à Microsoft.AspNet.OData.Routing.ODataRouteBindingInfoConvention.Apply(ActionDescriptorProviderContext context, ControllerActionDescriptor action)
   à Microsoft.AspNetCore.Mvc.ODataActionDescriptorProvider.OnProvidersExecuted(ActionDescriptorProviderContext context)
   à Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection()
   à Microsoft.Extensions.Primitives.ChangeToken.<>c__DisplayClass0_0.<OnChange>b__0(Object s)
   à Microsoft.AspNetCore.Mvc.ODataActionDescriptorChangeProvider.ChangeToken.Callback()
   à Microsoft.AspNetCore.Mvc.ODataActionDescriptorChangeProvider.NotifyChanged()
   à Microsoft.AspNet.OData.Extensions.IRouteBuilderExtensions.NotifyRoutesMapped()
   à Microsoft.AspNet.OData.Extensions.IRouteBuilderExtensions.MapVersionedODataRoutes(IRouteBuilder builder, String routeName, String routePrefix, IEnumerable`1 models, IODataPathHandler pathHandler, IEnumerable`1 routingConventions, Func`1 newBatchHandler)
   à Microsoft.AspNet.OData.Extensions.IRouteBuilderExtensions.MapVersionedODataRoutes(IRouteBuilder builder, String routeName, String routePrefix, IEnumerable`1 models)
   à WebApplication1.Startup.MvcOptions(IRouteBuilder routeBuilder, VersionedODataModelBuilder builder)
   à WebApplication1.Startup.<>c__DisplayClass1_0.<Configure>b__0(IRouteBuilder options)
   à Microsoft.AspNetCore.Builder.MvcApplicationBuilderExtensions.UseMvc(IApplicationBuilder app, Action`1 configureRoutes)
   à WebApplication1.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, VersionedODataModelBuilder builder)

Thanks for your help.

@commonsensesoftware
Copy link
Collaborator

This is almost certainly a bug in template generation. The need for convention-based template generation is primarily to support the API Explorer and ultimately Swagger. Unfortunately, I've yet to figure out delay this process. If you're not using this feature, you shouldn't have to pay for this type of issue.

I'll promote this to a bug once I confirm it. As a workaround, you can use attribute routing for this case, which defines the correct OData template.

Thanks.

@commonsensesoftware
Copy link
Collaborator

As expected by the stack trace presented, the multi-key template generation is not inserting required commas. This is should be a pretty simple fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants