Percy
Percy

Reputation: 3125

WebApi Routing issue - unable to route to required action

I've used the selected answer from here: Routing based on query string parameter name to build my routes but they don't work as expected:

my route:

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

my actions:

public string GetProductById(int id) {}
public string GetProductByIsbn(string isbn) {}

I am trying to call these via:

localhost:60819/api/products/id=33 //doesn't work
localhost:60819/api/products/33 //does work

and

http://localhost:60819/api/products/isbn=9781408845240 //doesn't work
http://localhost:60819/api/products/testString //test with a definite string - doesn't work - still tries to use GetProductById(int id)

the error is the same for both that don't work:

<Error><Message>The request is invalid.</Message>
    <MessageDetail>
        The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String GetProductById(Int32)' in 'BB_WebApi.Controllers.ProductsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
    </MessageDetail>
</Error>

Seems to think the id isn't being passed in...?

I've read up all the msdn docs but I seem to be missing something somewhere. Can anyone see where I'm going wrong?

Upvotes: 1

Views: 632

Answers (1)

JotaBe
JotaBe

Reputation: 39015

You've got several mistakes (and you're not showing all the relevant code, or you're showing the wrong code, as explained below, relating to the id in the route template).

localhost:60819/api/products/id=33 //doesn't work

This will never work. If you want to pass a named parameter in the URL you must use the query string, i.e, instead of /id=33, you need to use ?id=33

localhost:60819/api/products/33 //does work

With the route that you're showing, this can't work. You can pass parameters as URL segments only if you define those parameters in tyour route template. Your route template should look like this: api/{controller}/{id} so that the id can be recovered from the url, and this second URL really works.

http://localhost:60819/api/products/isbn=9781408845240 

Same as the second. Use ?isbn=9781408845240

http://localhost:60819/api/products/testString

This would only map the testString to a parameter in the route template. You'd need something like this: isbn=textString to be able to invoke the action of your interest.

So, remember this:

  • named parameters must be passed in the url query string, using the correct query string syntax, which is this: ?param1=val1&param2=val2
  • url segment parameters must exists in the route template. If not, it's impossible that the binder can do anything at all about them.

As it looks you're missing a lot of information, please, read this docs: Parameter Binding in ASP.NET Web API.

This can also be interesting for you: Attribute Routing in ASP.NET Web API 2, which allows you to use route attributes, which are much more flexible than route templates.

Upvotes: 2

Related Questions