0

I have added two GET methods into webapi as follow:

    public IList<ProductDTO> GetAllProducts()
    {
        ProductManager pm = new ProductManager();

        return pm.RetrieveAllProducts();
        //return pm.RetrieveAllProducts();
    }

    public ProductDTO GetProduct(int i)
    {
        ProductManager pm = new ProductManager();

        return pm.RetrieveAllProducts().Where(c => c.Id == i).FirstOrDefault();
        //return pm.RetrieveAllProducts();
    }

Problem, when i only kept one get method GetAllProducts() then it works fine. but when i added GetProduct(int i) then giving me error as Not found 404 error.

Please guide me how i could keep both the mthod and allow to access method having argument.

calling as follow:

           $.ajax({
            type: 'GET',
            url: 'api/values/GetProduct/1',   //giving error as NOT FOUND
            contentType: 'json',
            dataType: 'json',
            success: function (data) {
                $.each(data, function (key, value) {
                    //stringify
                    alert(key);
                    alert(value);
                    var jsonData = JSON.stringify(value);

                    //Parse JSON
                    var objData = $.parseJSON(jsonData);
                    var id = objData.Id;
                    var Cost = objData.Cost;
                    var ProductName = objData.ProductName;
                    var Description = objData.Description;
                    $('<tr><td>' + id + '</td><td>' + ProductName +
                    '</td><td>' + Cost + '</td></tr>').appendTo('#ProductDivWebApi');
                });
            },
            error: function (xhr) {
                alert(xhr.responseText);
            }
        });

i have added this WEBAPI into MVC 4 project.

its route shows as below:

   public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "ProductManagement", action = "Index", id = UrlParameter.Optional }
        );
      }

Please guide

user3711357
  • 1,425
  • 7
  • 32
  • 54

1 Answers1

1

The routes on the ASP.NET WEB API is different than ASP.NET MVC. You have the GET methods, so, just call the controller using the GET verb and the framework will solve it for you. I recommend you rename the methods to a verb, Get, Post, Put, Delete, etc.

In your case, call the method by /api/{controller}/{id}. In this case, data is a single object (because you have returned only a ProductDTO), so do not loop in it.

You have specified json, so jquery will be deserialized it in a object for you. For sample:

$.ajax({
    type: 'GET',
    url: 'api/values/1', 
    contentType: 'json',
    dataType: 'json',
    success: function (data) {
        // data is a single object, do not loop in it.
        // you have specified json, so, it will be deserialized     

        var id = data.Id;
        var Cost = data.Cost;
        var ProductName = data.ProductName;
        var Description = data.Description;

        $('<tr><td>' + id + '</td><td>' + ProductName +
        '</td><td>' + Cost + '</td></tr>').appendTo('#ProductDivWebApi');
        });
    },
    error: function (xhr) {
        alert(xhr.responseText);
    }
});

I also recommend you to do some things like this on Web API:

[HttpGet]
public HttpResponseMessage GetProduct(int id)
{
   ProductManager pm = new ProductManager();

   var result = pm.RetrieveAllProducts().Where(c => c.Id == id).FirstOrDefault();

   return Request.CreateResponse(HttpStatusCode.OK, result);
}

On the WebApiConfig.cs file I recommend you configure the routes like this:

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute("DefaultApiGet",
                                "api/{controller}",
                                new {action = "Get"},
                                new {httpMethod = new HttpMethodConstraint(HttpMethod.Get)});

    config.Routes.MapHttpRoute("DefaultApiGetWithId",
                                "api/{controller}/{id}",
                                new {id = RouteParameter.Optional, action = "Get"},
                                new {id = @"\d+"});

    config.Routes.MapHttpRoute("DefaultApiWithAction",
                                "api/{controller}/{action}");

    config.Routes.MapHttpRoute("DefaultApiWithActionAndId",
                                "api/{controller}/{action}/{id}",
                                new {id = RouteParameter.Optional},
                                new {id = @"\d+(_\d+)?"});
}
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
  • `api/values/1`, `api/values/GetAllProducts`, `api/values` these all three points to same methods `GetAllProducts`... but unable to call `public omega.learning.data.common.DTO.ProductDTO GetProduct(int i)` please help me how to call.. – user3711357 Aug 20 '14 at 17:30
  • Yup, it works... But why i am not able to call by Name. `api/values/GetProduct/1` and it works only when `api/values/1` Also, can we keep multiple get methods like `GetAllProducts()`, `GetAllProductTypes()`, `GetProductTypeById(int pId)` ??? – user3711357 Aug 20 '14 at 17:42
  • 1
    The default name for the argument is `id`, so, if the argument's name is different, you have to pass like a query string, for sample: `/api/values/GetProductTypeById?pId=1`. – Felipe Oriani Aug 20 '14 at 17:45
  • Now, when i add multiple methods - then giving me error as `Multiple actions were found that matches the request`... now, i have just additonally added- `GetAllProductTypes()` method.. – user3711357 Aug 20 '14 at 17:55
  • Please let me know if you fouund this should be another question then, i will raise one new one and complete this by marking answer.... – user3711357 Aug 20 '14 at 18:03
  • It is a conflict of actions. I think it is another question, but you could solve it creating a new routeMap, like [this link](http://stackoverflow.com/questions/14534167/multiple-actions-were-found-that-match-the-request-webapi) – Felipe Oriani Aug 20 '14 at 18:16