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

2

14

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?

Varicelloid answered 7/7, 2014 at 4:14 Comment(1)
Similar error here - #27825274Epiblast
C
14

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)
Counterproductive answered 9/7, 2014 at 8:23 Comment(6)
I get No HTTP resource was found that matches the request URI 'localhost/odata/Clients(Id=5)'.Varicelloid
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?Varicelloid
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 nothingVaricelloid
Did the change. still get No HTTP resource was found that matches the request URI 'localhost/odata/Clients(5)Varicelloid
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.Counterproductive
Great stuff. Thanks broFowliang
V
0

This route is incorrect: [ODataRoute("GetClients(Id={Id})")]

It should be: [ODataRoute("Clients({Id})")]

URL should be: http://localhost/odata/Clients(Id=5)

Varicelloid answered 7/7, 2014 at 16:51 Comment(2)
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.Counterproductive
Yes, can you show me how to get this to return many client models? ThanksVaricelloid

© 2022 - 2024 — McMap. All rights reserved.