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?

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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.
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).
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
You may need to set up a default value for the controller. see the edits
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:

2 Comments

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?
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..
0

Your ProductController should derive from ApiController, instead of Controller.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.