1

I have two httpGet methods in my api controller. I use attribute routing to differentiate between them. When I navigate to localHost/api/Lockers/availableLockers I get an error:

the parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Http.IHttpActionResult GetLocker(Int32)

In my Lockers api Controller:

 public IQueryable<Locker> GetLocker()
        {
            return db.Lockers;
        }


        [Route("availableLockers")]
        [HttpGet]
        public IQueryable<Locker> GetAvailableLockers()
        {
            return db.Lockers.Where(l => l.StudentId != null);
        }

[ResponseType(typeof(Locker))]
    public IHttpActionResult GetLocker(int id)
    {
        Locker locker = db.Lockers.Find(id);
        if (locker == null)
        {
            return NotFound();
        }

        return Ok(locker);
    }

What I tried:

Based on a previous Stackoverflow answer I added to my webAp.config

In webApi.config

config.MapHttpAttributeRoutes();

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

This does not change the error

Curious-programmer
  • 772
  • 3
  • 13
  • 31
  • The message states it executing a `GetLocker` method (which you have not shown). And you state your url is `localHost/Lockers/availableLockers` but that does not contain `/api/` in the route –  Mar 08 '18 at 05:08
  • Also you need to put specific route configuration before the default route configuration. – Chetan Mar 08 '18 at 05:11
  • Visit this for reference: https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 – Innocent Criminal Mar 08 '18 at 05:12
  • I can see 3 actionmethods in your above code. And to call these three as per your code routes will be like: 1. localhost/api/lockers 2. localhost/api/lockers/availableLockers 3. localhost/api/lockers/1 – Ankit Sahrawat Mar 08 '18 at 05:37
  • @ankit sahrawat. I edited the question. – Curious-programmer Mar 08 '18 at 06:21

2 Answers2

1

Add RoutePrefix attribute on your controller as below:

[RoutePrefix("api/Lockers")]
public class LockersController : ApiController
{

}

After adding RoutePrefix on your controller your route: localHost/api/Lockers/availableLockers will start working. Currently it is throwing exception because application is considering it as id=applicationLockers which expects last parameter as int

Ankit Sahrawat
  • 1,306
  • 1
  • 11
  • 24
0

It was your routing attribute. It should have been:

    [Route("api/Lockers/availableLockers")]
    [HttpGet]
    public IQueryable<Locker> GetAvailableLockers()
    {
        return db.Lockers.Where(l => l.StudentId != null);
    }
Bob Dust
  • 2,370
  • 1
  • 17
  • 13