1

My ajax calls the wrong method in .net mvc 4 and I can't figure out why.

My ajax:

function addItem(id, ammount) {
$.ajax({
    url: "/Shoppingcart/AddItem?id="+id+"&ammount="+ammount,
    type: "post",
    cache: false,
    success: function (result) {
        alert("SUCCESS!!!");
    },
    error: function (textStatus, errorThrown) {
        window.console.log(textStatus, errorThrown);
    }
});
}

My mvc controller:

public class ShoppingcartController : Controller
{
    //
    // GET: /Shoppingcart/

    public ActionResult Index()
    {
        // Method 1
    }

    [HttpPost]
    public ActionResult AddItem(int id = -1, int ammount = 0)
    {
        return Redirect("~/Home");
    }
}

My first method is getting called by the ajax, which is strange since I call /Shoppingcart/AddItem Why is this happening and what should I do to make it work?

Solution: The problem was not in the method calling but in the route stack. Apperantly the order in wich the routes are defined influences their importancy. The most specific route should always be the first route to be declared.

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

        routes.MapRoute(
            name: "Index",
            url: "{controller}/{id}",
            defaults: new { controller = "Home", action = "Index" },
            constraints: new { id = @"\d+" }
        );

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

        routes.MapRoute(
            name: "ControllerOnly",
            url: "{controller}",
            defaults: new { controller = "Home", action = "Index", id = 0 }
        );
    }
MichielDeRouter
  • 426
  • 4
  • 21
  • You code looks fine, are you sure the the `addItem` function is called? Please check in fiddler/dev-console/firebug which requests do you sent to the server. – nemesv Oct 22 '12 at 14:06
  • According to fiddler the url http://localhost:1862/Shoppingcart/AddItem?id=18&ammount=1 is being called. On additon to the above my succes message is triggerd correctly – MichielDeRouter Oct 22 '12 at 14:11
  • Do you have any custom routes if yes please post your routing config? – nemesv Oct 22 '12 at 14:13
  • according to the jQuery documentation you should use "POST" instead of "post", but i really doubt that it changes anything... :-) Perhaps you should use "data" instead of the querystring also. – jovnas Oct 22 '12 at 14:13
  • nemesv I added the routeconfig to the post. jovnas I tried using data, no effect. – MichielDeRouter Oct 22 '12 at 14:19

1 Answers1

3

The problem is with your routing because the configured routes are matched in order.

So first you should put the more specify ones and at the end the more generic ones.

You have to most generic route with url: "{controller}" first which matches the url localhost:1862/Shoppingcart/AddItem?id=18&ammount=1 and uses the action = "Index" instead of the action AddItem.

To fix it change your route order to:

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

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

routes.MapRoute(
    name: "ControllerOnly",
    url: "{controller}",
    defaults: new { controller = "Home", action = "Index", id = 0 }
);

To make urls like /Product/18 route correctly you need to change your "Index" route with using a constraint on id instead of UrlParameter.Optional and you need to put it before the "Default" route:

routes.MapRoute(
    name: "Index",
    url: "{controller}/{id}",
    defaults: new { controller = "Home", action = "Index" },
    constraints: new {id = @"\d+"}
);
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • It sounds logical, however when I apply the above "Solution" my http://localhost:1862/Product/18 doesnt work anymore – MichielDeRouter Oct 22 '12 at 14:37
  • Great! It now (sort of) works! Atleast the fuction is getting called, however (see updated question) my redirect is just ignored. How come? (The line is fired according to my debugger but no action is taken) – MichielDeRouter Oct 22 '12 at 14:57
  • If the routing is working then your question in answered. Why is the Redirect is "ignored" is a different question, but I can answer it now: **Redirect does not work inside AJAX requests**: see this SO question for solutions: http://stackoverflow.com/questions/199099/how-to-manage-a-redirect-request-after-a-jquery-ajax-call – nemesv Oct 22 '12 at 15:01