0

My controller currently looks like:

[Jsonp filter] 
public class ProductController : Controller
{

     public Json GetProduct(string id)
     {
          Product x;
          //code
          return Json(x, JsonRequestBehavior.AllowGet);
     }
 }

I am able to get a product doing this: api/product/getproduct/5

But, I want to be able to access it like this: api/product/5

What change do I need to make to do this?

EDIT: I am actually using Jsonp because I need to call this API from a different domain and get a json object back. Would this be possible using ApiController? Otherwise is there a way to do this without switching to ApiController?

user2463517
  • 197
  • 1
  • 5
  • 14

4 Answers4

3

You will have to edit your webapiconfig (located in the App_Start folder).

You will need to add something like this before any other route (to make sure it is caught first):

// Map Http Route takes in 3 parameters below
// param 1 is the name of the route.. This has nothing to do with class names or method names
// param 2 is the route itself.  Route parameters are denoted in curly braces {likethis}
// param 3 sets up defaults
config.Routes.MapHttpRoute("GetProductApi", "api/product/{id}",
    new {
        controller = "Product",      // the name of the controller class (without the Controller suffix)
        action = "GetProduct",       // the name of your method
        id = RouteParameter.Optional
    });

Also, your code for your controller looks like it isn't an API controller. Regardless, this is a routing problem. You can add a route configuration in your regular route config if you 100% need to.

Kenny Thompson
  • 1,494
  • 12
  • 28
  • I am confused why this is even necessary. The default routing should allow you to skip the /getproduct/ part of the URL if that is the only GET operation. – Moby Disk Aug 12 '14 at 21:11
  • I think he would need to change the `GetProduct` method name to just `Get`? Maybe he would need to add the `[HttpGet]` method attribute? Either way adding a specific route will get him there (not that it is the best solution). – Kenny Thompson Aug 12 '14 at 21:15
  • Hmm, I tried this and it doesn't seem to be working.. I added exactly what you typed except changed the "GetProductApi" to the name of my actual Api – user2463517 Aug 12 '14 at 21:23
  • You may need to set up a default value for the controller. see the edits – Kenny Thompson Aug 13 '14 at 14:22
1

Your code above is not a WebApi Controller it is an MVC Controller. Your class needs to inherits from ApiController instead like:

public class ProductController : ApiController{
...

Regarding your method I am not sure why you used Json as returned type since it is part of the MediaFormatter configuration to define the returned format, it should not be defined at method/function level. It looks like the correct method declaration will be something like:

public Product GetProduct(string id)
{
   Product x; //probably you want initialize it like new Product();       
   return x;
}

Update JsonP

WebApi works based on MediaFormatters as explained earlier. In order to use JsonP you need to use the proper media formatter there are several out there but how about:

http://www.nuget.org/packages/WebApi.JsonP

If you wish to read more about JsonP formatters for WebApi here is a SO Post about this:

Community
  • 1
  • 1
Dalorzo
  • 19,834
  • 7
  • 55
  • 102
  • I actually have to use JsonP because I am accessing this API from a different domain, I will update the question to include this. Is there any way to do this without changing to ApiController because I don't think APIController would support JsonP? – user2463517 Aug 12 '14 at 21:02
  • This is the correct way to do this I'm guessing but I don't have the option of switching this right now. I'll mark it as correct anyways.. – user2463517 Aug 12 '14 at 21:22
0

Your ProductController should derive from ApiController, instead of Controller.

Przemysław Kalita
  • 1,977
  • 3
  • 18
  • 28
0

Building on @Dalorzo's answer, if/when you can convert to an APIController, and if you can use WebAPI 2, you can use decorator attributes on your methods that will alter the routes and even the HTTP verbs to use for the method... which is really nice because everything you need to know about that API call is right there at the function signature. It's quite robust and intuitive, and I highly recommend it.

Clever Neologism
  • 1,322
  • 8
  • 9