Skip to content

CreateRef and DeleteRef Issue #573

Closed
@Diraekt

Description

@Diraekt

I'm using Version 4.0.0-preview8.19405.7 which works great, thanks 👍
Yesterday I updated to Version 4.0.0 and running into the following issue (see bellow please).

Setup:
All Controllers inherit from a BaseController. The BaseController got the following definition which makes problem in 4.0.0.

       [AcceptVerbs("POST", "PUT")]
        public IActionResult CreateRef([FromODataUri] int key, [FromODataUri] string navigationProperty, [FromBody] Uri link)
        {
        }
public IActionResult DeleteRef([FromODataUri] int key, [FromODataUri]string navigationProperty, [FromBody] Uri link)
        {
           
        }
app.UseMvc(b =>
                     {
                         b.MapVersionedODataRoutes("ODataRoute", "odata/v{v:apiVersion}", GetPublicModels(modelBuilder), ConfigureAction);
                    });

In Version 4.0.0-preview8.19405.7 the recognized Path-Template is:
EntityName/{key}
where the recognized Path-Template in Version 4.0.0 is:
EntityName/{key}/{navigationProperty}/$ref

(Value from: ActionParameterContext ctor - odataPathTemplate variable)

Because of this, in the method TryGetNextSegmentText from the Odata.Core Lib, we have now 3 Segments. The last one is {navigationProperty} (PathTemplateSegment) with TargetKind Nothing, so the exception will throw.

Exception on AppStart:

ODataUnrecognizedPathException: The request URI is not valid. The segment '{navigationProperty}' must be the last segment in the URI because it is one of the following: $ref, $batch, $count, $value, $metadata, a named media resource, an action, a noncomposable function, an action import, a noncomposable function import, an operation with void return type, or an operation import with void return type. Microsoft.OData.UriParser.ODataPathParser.ThrowIfMustBeLeafSegment(ODataPathSegment previous) Microsoft.OData.UriParser.ODataPathParser.TryGetNextSegmentText(bool previousSegmentWasEscapeMarker, out string segmentText) Microsoft.OData.UriParser.ODataPathParser.ParsePath(ICollection<string> segments) Microsoft.OData.UriParser.ODataPathFactory.BindPath(ICollection<string> segments, ODataUriParserConfiguration configuration) Microsoft.OData.UriParser.ODataUriParser.ParsePathImplementation() Microsoft.OData.UriParser.ODataUriParser.Initialize() Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.Parse(string serviceRoot, string odataPath, IServiceProvider requestContainer, bool template) Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.ParseTemplate(string odataPathTemplate, IServiceProvider requestContainer) Microsoft.AspNet.OData.Routing.ActionParameterContext..ctor(ODataRouteBuilder routeBuilder, ODataRouteBuilderContext routeContext) Microsoft.AspNet.OData.Routing.ODataRouteBindingInfoConvention.UpdateBindingInfo(ControllerActionDescriptor action, ODataRouteMapping mapping, ICollection<ODataAttributeRouteInfo> 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.<OnChange>b__0_0(Action callback) Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration<TState>.OnChangeTokenFired() Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration<TState>+<>c.<RegisterChangeTokenCallback>b__7_0(object s) Microsoft.AspNetCore.Mvc.ODataActionDescriptorChangeProvider+ChangeToken.Callback() Microsoft.AspNetCore.Mvc.ODataActionDescriptorChangeProvider.NotifyChanged() Microsoft.AspNet.OData.Extensions.IRouteBuilderExtensions.MapVersionedODataRoutes(IRouteBuilder builder, string routeName, string routePrefix, IEnumerable<IEdmModel> models, Action<IContainerBuilder> configureAction, Action<ODataConventionConfigurationContext> configureRoutingConventions) Microsoft.AspNet.OData.Extensions.IRouteBuilderExtensions.MapVersionedODataRoutes(IRouteBuilder builder, string routeName, string routePrefix, IEnumerable<IEdmModel> models, Action<IContainerBuilder> configureAction) OrphyApi.Startup+<>c__DisplayClass28_0.<Configure>b__0(IRouteBuilder b) in Startup.cs + b.MapVersionedODataRoutes("ODataRoute", "odata/v{v:apiVersion}", GetPublicModels(modelBuilder), ConfigureAction); Microsoft.AspNetCore.Builder.MvcApplicationBuilderExtensions.UseMvc(IApplicationBuilder app, Action<IRouteBuilder> configureRoutes) OrphyApi.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, VersionedODataModelBuilder modelBuilder, IApiVersionDescriptionProvider provider) in Startup.cs + app.UseMvc(b => Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app) Microsoft.AspNetCore.Mvc.Internal.MiddlewareFilterBuilderStartupFilter+<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder) Microsoft.Extensions.DependencyInjection.AutoRegisterMiddleware+<>c__DisplayClass4_0.<Configure>b__0(IApplicationBuilder app) Microsoft.AspNetCore.Server.IISIntegration.IISSetupFilter+<>c__DisplayClass4_0.<Configure>b__0(IApplicationBuilder app) Microsoft.AspNetCore.HostFilteringStartupFilter+<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app) Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter+<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder) Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication().

How we can fix it ?

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions