I created a dummy project to test Odata in VS2015 and I was having an exactly the same issue as described in this question, and my code is largely equivalent to what is described there. Web API 2: OData 4: Actions returning 404
Any query to a bound function gives a 404 error until you add a trailing slash. For example:
http://localhost:46092/odata/v1/Trips/Default.GetTripNameById - 404 http://localhost:46092/odata/v1/Trips/Default.GetTripNameById/ - works as expected
http://localhost:46092/odata/v1/Trips/Default.GetTripNameById(tripID=1)?$select=Name - 404 http://localhost:46092/odata/v1/Trips/Default.GetTripNameById(tripID=1)/?$select=Name - works as expected
This is not supposed to happen because Microsoft documentation never mentions that a trailing slash is required, their examples are supposed to work without them. Also, this breaks the Swagger UI which doesn't add a trailing slash and gets 404 when trying to make any query.
What could be the reason for this behaviour? How do I make it work without a slash, which seems to be the normal expected behaviour?
Here are my code snippets:
TripsController.cs:
    ...
    [HttpGet]
    public IHttpActionResult GetTripNameById(int tripID)
    {
        return Ok(DemoDataSources.Instance.Trips.AsQueryable().Where(t => t.ID == tripID.ToString()));
    }
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.MapODataServiceRoute("odata", "odata/v1", GetEdmModel());
DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
        config.EnsureInitialized();
    }
    private static IEdmModel GetEdmModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Person>("People");
        builder.EntitySet<Trip>("Trips");
        builder.EntityType<Trip>().Collection.Function("GetTripNameById").Returns<string>().Parameter<int>("tripID");
        var edmModel = builder.GetEdmModel();
        return edmModel;
    }
