0
votes

I am working on ASP.NET Core 2.2 Web API that uses OData(Open Data Protocol) version 7.2.1.

It works fine with conventional routing.I want to add attribute routing in action method so that I can overload methods.But no success in that.

I did not get any documentation on OData web site that works for me. Here is my code.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData.Edm;
using ODataService.Model;
using System.Linq;

namespace ODataService
{
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //Adding In Memory Database.
        services.AddDbContext<SampleODataDbContext>(options =>
        {
            options.UseInMemoryDatabase("InMemoryDb");
        });

        //Adding OData middleware.
        services.AddOData();

        services.AddMvc(options =>
        {
            options.EnableEndpointRouting = false;
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        //app.UseMvc();


        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Person>(nameof(Person));

        //Enabling OData routing/web api routing
        app.UseMvc(routeBuilder =>
        {
            routeBuilder.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");


            routeBuilder.MapODataServiceRoute(
                            routeName: "ODataRoute",
                            routePrefix: "odata",
                            model: builder.GetEdmModel()
                            );


            routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();


            //routeBuilder.EnableDependencyInjection();
        });



    }

 }
}


//Here is controller class

using System;
using System.Linq;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
using ODataService.Model;
using Microsoft.AspNet.OData.Routing;
using System.Threading.Tasks;

namespace ODataService.Controllers
{


[Route("api/[controller]")]
//[ODataRouting()]
[ODataRoutePrefix("Person")]
[ApiController]
public class PersonController : ODataController
{

    private readonly SampleODataDbContext _appDbContext;
    public PersonController(SampleODataDbContext sampleODataDbContext)
    {
        _appDbContext = sampleODataDbContext;
    }

    //[ODataRoute("GetAllPerson")]
    [EnableQuery(AllowedArithmeticOperators =Microsoft.AspNet.OData.Query.AllowedArithmeticOperators.None)]
    public IActionResult Get()
    {
        var NewPerson1 = new Person
        {
            Age = 20,
            Id = new Guid(),
            Name = "test"
        };


        Person NewPerson2 = new Person
        {
            Age = 25,
            Id = new Guid(),
            Name = "test jai"
        };

        _appDbContext.Persons.Add(NewPerson1);
        _appDbContext.SaveChanges();
        _appDbContext.Persons.Add(NewPerson2);
        _appDbContext.SaveChanges();
        return Ok(_appDbContext.Persons.AsQueryable());
    }



    //[ODataRoute("GetData")]
    [EnableQuery(AllowedArithmeticOperators = Microsoft.AspNet.OData.Query.AllowedArithmeticOperators.None)]
    public IActionResult GetData()
    {
        var NewPerson1 = new Person
        {
            Age = 20,
            Id = new Guid(),
            Name = "abcd efgh"
        };




        _appDbContext.Persons.Add(NewPerson1);
        _appDbContext.SaveChanges();

        return Ok(_appDbContext.Persons.AsQueryable());
    }

    [Route("GetAllEmployee")]
    public IActionResult GetAll()
    {
        Person NewPerson1 = new Person
        {
            Age = 20,
            Id = new Guid(),
            Name = "test"
        };


        Person NewPerson2 = new Person
        {
            Age = 25,
            Id = new Guid(),
            Name = "test jai"
        };

        _appDbContext.Persons.Add(NewPerson1);

        _appDbContext.SaveChanges();


        _appDbContext.Persons.Add(NewPerson2);
        _appDbContext.SaveChanges();
        return Ok(_appDbContext.Persons.AsQueryable());
    }
 }
}

I want to execute both the below given URL

http://localhost:5000/OData/Person/GetData

http://localhost:5000/OData/Person

Any Suggestion?

1
The issue seems to be a general problem , you could post a issue on ODataRoute attribute at here .And you could refer to the workaround that I post below. - Xueli Chen

1 Answers

0
votes

After long experiment using attribute routing, functions and actions, the above can be achieved using the OData functions.

Below is the code for it.

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Person>(nameof(Person)).EntityType.Collection.Function("GetData").Returns<Person>();

Refer the below for more understanding.

https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions