The path template on the action in controller is not a valid OData path template

24,334

You don't even need to add such a function to get an entity.

builder.EntitySet<ClientModel>("Clients")

is all you need.

And then write your action as:

public IHttpActionResult GetClientModel([FromODataUri] int key)
{    
      return Ok(_clientsRepository.GetClients(key).Single());
}

Or

This is what worked. The above did not work:

public IHttpActionResult Get([FromODataUri] int key)
{    
    return Ok(_clientsRepository.GetClients(key).Single());
}

Then the Get request

http://localhost/odata/Clients(Id=5)

or

http://localhost/odata/Clients(5)

will work.

Update: Use unbound function to return many ClientModels.

The follow code is for v4. For v3, you can use action.

builder.EntitySet<ClientModel>("Clients");
var function = builder.Function("FunctionName");
function.Parameter<int>("Id");
function.ReturnsCollectionFromEntitySet<ClientModel>("Clients");

Add a method in the controller like:

[HttpGet]
[ODataRoute("FunctionName(Id={id})")]
public IHttpActionResult WhateverName(int id)
{
    return Ok(_clientsRepository.GetClients(id));
}

Send a request like:

GET ~/FunctionName(Id=5)
Share:
24,334
Nate
Author by

Nate

Updated on July 09, 2022

Comments

  • Nate
    Nate almost 2 years

    I am getting the following error:

    The path template 'GetClients()' on the action 'GetClients' in controller 'Clients' is not a valid OData path template. Resource not found for the segment 'GetClients'.

    My controller method looks like this

    public class ClientsController : ODataController
    {
        [HttpGet]
        [ODataRoute("GetClients(Id={Id})")]
        public IHttpActionResult GetClients([FromODataUri] int Id)
        {
            return Ok(_clientsRepository.GetClients(Id));
        }
    }
    

    My WebAPIConfig file has

    builder.EntityType<ClientModel>().Collection
           .Function("GetClients")
           .Returns<IQueryable<ClientModel>>()
           .Parameter<int>("Id");
    
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: "odata",
        model: builder.GetEdmModel());
    

    I am hoping to be able to call the odata rest api like this:

    http://localhost/odata/GetClients(Id=5)
    

    Any idea what I am doing wrong?

  • Feng Zhao
    Feng Zhao almost 10 years
    With [ODataRoute("Clients({Id})")], the function you defined in the model is never used. If you really want function "GetClients" to return many ClientModels, I can provider with code to do that.
  • Nate
    Nate almost 10 years
    I get No HTTP resource was found that matches the request URI 'localhost/odata/Clients(Id=5)'.
  • Nate
    Nate almost 10 years
    I am using Odata v3 because I am using jaydata which uses Odata and they do not seem to work with v4. How does routing work with v3?
  • Nate
    Nate almost 10 years
    I changed it to use v4 and I followed your instruction but now I get no data return. localhost/odata/$metatdata works but localhost/odata/Clients(5 returns nothing
  • Nate
    Nate almost 10 years
    Yes, can you show me how to get this to return many client models? Thanks
  • Nate
    Nate almost 10 years
    Did the change. still get No HTTP resource was found that matches the request URI 'localhost/odata/Clients(5)
  • Feng Zhao
    Feng Zhao almost 10 years
    The difference of two methods is only with the name. The "GetClientModel(int key)" will be matched firstly, and then the "Get(int key)" will be matched. As you said, the latter one works but the previous one doesn't, is the reason that the name of the entity type is not equal to "ClientModel"? Two methods both work on my machine.
  • Hugo Nava Kopp
    Hugo Nava Kopp about 7 years
    Great stuff. Thanks bro