WebApi icon indicating copy to clipboard operation
WebApi copied to clipboard

ODataRoute template does not support some symbols .NET Core

Open komdil opened this issue 4 years ago • 3 comments

I was using _ character in .net. I am trying to migrate to .Net Core. But getting an error on putting _ to ODataRoute

Assemblies affected

I am using Microsoft.AspNetCore.OData

Reproduce steps

Put _ symbol in ODataRoute:

public class StudentController : BaseController<Student>
   {
       [EnableQuery]
       [ODataRoute("Student_ByID(Id={key})")]
       public IActionResult Student(string key)
       {
           return Get("Id", key);
       }
   }

Configuration:

public static class Configuration
    {
        public static Action<IApplicationBuilder> ConvertToAppBuilder(Action<object> myActionT)
        {
            if (myActionT == null) return null;
            else return new Action<object>(o => myActionT(o));
        }


        public static Action<IApplicationBuilder> GetBuilder()
        {
            return ConvertToAppBuilder(Configure);
        }

        public static void Configure(object appBuilder)
        {
            var app = appBuilder as IApplicationBuilder;
            var builder = new ODataConventionModelBuilder(app.ApplicationServices);
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseODataBatching();

            app.UseAuthentication();
            app.UseAuthorization();

            var edmModel = GetEdmModel(builder);
            app.UseDeveloperExceptionPage();
            app.UseEndpoints(routeBuilder =>
            {
                routeBuilder.EnableDependencyInjection();
                routeBuilder.Select().Filter().Expand();
                routeBuilder.MapODataRoute("OData", "odata", b =>
                {
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => edmModel);
                    var customRoutingConvention = new ODataCustomRoutingConvention();
                    var conventions = ODataRoutingConventions.CreateDefault();
                    //Workaround for https://github.com/OData/WebApi/issues/1622
                    conventions.Insert(0, new AttributeRoutingConvention("OData", app.ApplicationServices, new DefaultODataPathHandler()));
                    //Custom Convention
                    conventions.Insert(0, customRoutingConvention);
                    b.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, a => conventions);
                });
            });
        }

        static IEdmModel GetEdmModel(ODataConventionModelBuilder builder)
        {
            builder.EntityType<Student>().HasKey(a => a.Id);
            builder.EntitySet<Student>("Student");
            builder.Function("Student").ReturnsFromEntitySet<Student>("Student").Parameter<string>("Id");

            return builder.GetEdmModel();
        }
    }

Expected result

I was working on .Net. It should work in .NET Core

Actual result

It is throwing an exception:

System.InvalidOperationException: The path template 'Student_ByID(Id={key})' on the action 'Student' in controller 'Student' is not a valid OData path template. Resource not found for the segment 'Student_ByID'.
   at Microsoft.AspNet.OData.Routing.Conventions.AttributeRoutingConvention.GetODataPathTemplate(String prefix, String pathTemplate, IServiceProvider requestContainer, String controllerName, String actionName)
   at Microsoft.AspNet.OData.Routing.Conventions.AttributeRoutingConvention.<>c__DisplayClass11_0.<GetODataPathTemplates>b__1(ODataRouteAttribute route)
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at Microsoft.AspNet.OData.Routing.Conventions.AttributeRoutingConvention.BuildAttributeMappings(IEnumerable`1 controllerActions)
   at Microsoft.AspNet.OData.Routing.Conventions.AttributeRoutingConvention.get_AttributeMappings()
   at Microsoft.AspNet.OData.Routing.Conventions.AttributeRoutingConvention.SelectAction(RouteContext routeContext)
   at Microsoft.AspNet.OData.Routing.ODataActionSelector.SelectCandidates(RouteContext context)
   at Microsoft.AspNet.OData.Extensions.ODataEndpointRouteValueTransformer.TransformAsync(HttpContext httpContext, RouteValueDictionary values)
   at Microsoft.AspNetCore.Mvc.Routing.DynamicControllerEndpointMatcherPolicy.ApplyAsync(HttpContext httpContext, CandidateSet candidates)
   at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.SelectEndpointWithPoliciesAsync(HttpContext httpContext, IEndpointSelectorPolicy[] policies, CandidateSet candidateSet)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.<Invoke>g__AwaitMatch|8_1(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
   at Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(Object requestContextObj)
   at Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(Object requestContextObj)

komdil avatar Jul 12 '20 06:07 komdil

@komdil how do you want the URL to look like? Do you want to create a function or just query by key?

ElizabethOkerio avatar Jul 14 '20 16:07 ElizabethOkerio

@komdil Was this issue resolved?

KenitoInc avatar May 18 '22 08:05 KenitoInc

I don't know. Did you check the steps?

komdil avatar May 18 '22 09:05 komdil

Closing this issue due to inactivity. If this issue still persists, feel free to create a new issue.

KenitoInc avatar Feb 10 '23 08:02 KenitoInc