1
votes


I'm using OData V3 with MVC4 Web API project .NET4.
The WebAPI register method is:

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling =
                  Newtonsoft.Json.PreserveReferencesHandling.None;

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<ClientModel>("ODClient");
            builder.ComplexType<ClientStatus>();
            builder.ComplexType<ClientType>();

            var edmmodel = builder.GetEdmModel();

            config.Routes.MapODataRoute(
                    routeName: "odata",
                    routePrefix: "odata",
                    model: edmmodel
            );
        }

The OData controller is:

        [HttpGet]
        [Queryable(AllowedQueryOptions = AllowedQueryOptions.All, PageSize = 25)]
        public IQueryable<ClientModel> Get() 
        {
            var model = ...
            return model;
        }

        [HttpGet]
        public ClientModel Get([FromODataUri] int id)
        {
            return new ClientModel();
        }

    [HttpDelete]
    public void Delete([FromODataUri] int id)
    {
    }

This query runs well:
http://localhost:59661/odata/ODClient?$filter=id eq 3

But this query doesn't work:
http://localhost:59661/odata/ODClient(3)
It executes first GET query with all items.

The Delete doesn't work either (the request type is DELETE):
http://localhost:59661/odata/ODClient(3)

The error received is:
"No HTTP resource was found that matches the request URI 'http://localhost:59661/odata/ODClient(12)'."

1
Does it work if, in your method declarations, you call the parameter "key" instead of "id"? - Brad
That's true. Changing method argument to "key" made it working! - mirik

1 Answers

0
votes

As per question comments, the issue was the way that the default routing conventions assigns a name to parameters. Keys are actually given the default name of "key" and so switching to that worked.

The name can be customized by either creating a custom routing convention that populates the route data table with a "id" value, or by using attribute based routing in which case the parameter name can match the name specified in the path template.