Search code examples
c#asp.netasp.net-web-apiodataasp.net-web-api-routing

C# WebApi Controller (States Controller Currently has 2 Get methods, 1 returns List, the second returns Single Item)


My WebApiConfig:

 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();


            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Applicant>("Applicants");
            builder.EntitySet<Country>("Countries");
            builder.EntitySet<Program>("Programs");
            builder.EntitySet<Campus>("Campuses");
            builder.EntitySet<AcademicYear>("AcademicYears");
            builder.EntitySet<Citizenship>("Citizenships");
            builder.EntitySet<ProgramChoice>("ProgramChoices");
            builder.EntitySet<Application>("Applications");
            builder.EntitySet<ProvinceState>("States");

            config.MapODataServiceRoute(
              routeName: "ODataRoute",
              routePrefix: null,
              model: builder.GetEdmModel());




            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{key}",
                defaults: new { key = RouteParameter.Optional }
            );
        }
    }

My Controller Get Method Returning a List of Items:

   [EnableQuery]
        public IQueryable<ProvinceState> Get()
        {
            return db.ProvinceStates;
        }

My Controller Get Method Returning a Single Item:

[EnableQuery]
public SingleResult<ProvinceState> Get([FromODataUri] string key)
{
    IQueryable<ProvinceState> result = db.ProvinceStates.Where(c => c.ProvinceStateCode == key);
    return SingleResult.Create(result);
}

The Problem is as follows:

  • When i do a request LocalHost:###/States , the Get methods returns the list of states properly without any problem.
  • But when i do a request LocalHost:###/States('AL') , to get a specific item back, i get the following error.

HTTP Error 404.0 - Not Found

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

When Debugging, and at the time of making the request to the get method that returns a single item, the debugger doesn't hit break-point for the single item GET. But it does when requesting the List GET method.

Any Advice or help would be greatly appreciate, thanks in advance.


Solution

  • Since you have a composite key consisting of ProvinceStateCode and CountryCode, you need to modify your Get method to accept both values.

    [HttpGet]
    [ODataRoute("States(ProvinceStateCode={stateCode},CountryCode={countryCode})")]
    [EnableQuery]
    public IHttpActionResult Get([FromODataUri] string stateCode, [FromODataUri] string countryCode)
    {
        var result = db.ProvinceStates.FirstOrDefault(c => c.ProvinceStateCode == stateCode && c.CountryCode == countryCode);
    
        if (result == null)
        {
            return NotFound();
        }
        else
        {
            return Ok(result);
        }
    }
    

    And then retrieve individual states as follows:

    GET http://host/States(ProvinceStateCode='AL',CountryCode='US')