2

I am trying to use ajax.actionlink to remove the number of items in my shoppingcart. I added an ajax.actionlink which works fine on my local computer (with Visual Studio 2010), but not on my server. Here is the code:

@Ajax.ActionLink("-",
            "RemoveQuantityFromProduct",
            "ShoppingCart",
            new { productId = item.Id.ToString() },
            new AjaxOptions
            {
                UpdateTargetId = "AjaxMiniShoppingCart",
                HttpMethod = "POST",
                InsertionMode = InsertionMode.Replace,
                OnSuccess="toggleCart",
            })

On my local computer the resulting link is: http://localhost:2565/shoppingcart/removequantityfromproduct/16

On my server however the resulting link is instead: http://www.domain.com/shoppingcart/removequantityfromproduct?productId=16

Both links works on the local computer, but both links results in a 404-error on the server.

Do anyone know why the url is different on the server and the local computer? Can anyone explain why the routing works on the local computer but not on the server?

(I am using nopCommerce 2.1 as a base for this webshop.)

[EDIT: Corrected the resulting URL:s. I typed the URL for adding a product instead of the URL for removing a product.] 2011-10-10 11:23

[EDIT added the RouteProvider.cs from NopCommerce] 2011-10-10 11:30

            //home page
            routes.MapLocalizedRoute("HomePage",
                            "",
                            new { controller = "Home", action = "Index"},
                            new[] { "Nop.Web.Controllers" });

            //products
            routes.MapLocalizedRoute("Product",
                            "p/{productId}/{SeName}",
                            new { controller = "Catalog", action = "Product", SeName = UrlParameter.Optional },
                            new { productId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RecentlyViewedProducts",
                            "recentlyviewedproducts/",
                            new { controller = "Catalog", action = "RecentlyViewedProducts" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RecentlyAddedProducts",
                            "newproducts/",
                            new { controller = "Catalog", action = "RecentlyAddedProducts" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RecentlyAddedProductsRSS",
                            "newproducts/rss",
                            new { controller = "Catalog", action = "RecentlyAddedProductsRss" },
                            new[] { "Nop.Web.Controllers" });

            //comparing products
            routes.MapLocalizedRoute("AddProductToCompare",
                            "compareproducts/add/{productId}",
                            new { controller = "Catalog", action = "AddProductToCompareList" },
                            new { productId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("CompareProducts",
                            "compareproducts/",
                            new { controller = "Catalog", action = "CompareProducts" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RemoveProductFromCompareList",
                            "compareproducts/remove/{productId}",
                            new { controller = "Catalog", action = "RemoveProductFromCompareList"},
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("ClearCompareList",
                            "clearcomparelist/",
                            new { controller = "Catalog", action = "ClearCompareList" },
                            new[] { "Nop.Web.Controllers" });

            //product email a friend
            routes.MapLocalizedRoute("ProductEmailAFriend",
                            "productemailafriend/{productId}",
                            new { controller = "Catalog", action = "ProductEmailAFriend" },
                            new { productId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });

            //catalog
            routes.MapLocalizedRoute("Category",
                            "c/{categoryId}/{SeName}",
                            new { controller = "Catalog", action = "Category", SeName = UrlParameter.Optional },
                            new { categoryId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("ManufacturerList",
                            "manufacturer/all/",
                            new { controller = "Catalog", action = "ManufacturerAll" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("Manufacturer",
                            "m/{manufacturerId}/{SeName}",
                            new { controller = "Catalog", action = "Manufacturer", SeName = UrlParameter.Optional },
                            new { manufacturerId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });

            //reviews
            routes.MapLocalizedRoute("ProductReviews",
                            "productreviews/{productId}",
                            new { controller = "Catalog", action = "ProductReviews" },
                            new[] { "Nop.Web.Controllers" });

            //login, register
            routes.MapLocalizedRoute("Login",
                            "login/",
                            new { controller = "Customer", action = "Login" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("LoginCheckoutAsGuest",
                            "login/checkoutAsGuest",
                            new { controller = "Customer", action = "Login", checkoutAsGuest = true },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("Register",
                            "register/",
                            new { controller = "Customer", action = "Register" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("Logout",
                            "logout/",
                            new { controller = "Customer", action = "Logout" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RegisterResult",
                            "registerresult/{resultId}",
                            new { controller = "Customer", action = "RegisterResult" },
                            new { resultId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });


            //shopping cart
            routes.MapLocalizedRoute("AddProductToCart",
                            "cart/addproduct/{productId}",
                            new { controller = "ShoppingCart", action = "AddProductToCart" },
                            new { productId = @"\d+" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("ShoppingCart",
                            "cart/",
                            new { controller = "ShoppingCart", action = "Cart" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("AjaxShoppingCart",
                            "cart/",
                            new { controller = "ShoppingCart", action = "Cart" },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("AddQuantity",
                            "shoppingcart/addquantitytoproduct/{productId}",
                            new { controller = "ShoppingCart", action = "AddQuantityToProduct", productId = UrlParameter.Optional },
                            new[] { "Nop.Web.Controllers" });
            routes.MapLocalizedRoute("RemoveQuantity",
                            "shoppingcart/removequantityfromproduct/{productId}",
                            new { controller = "ShoppingCart", action = "RemoveQuantityFromProduct", productId = UrlParameter.Optional },
                            new[] { "Nop.Web.Controllers" });

Action method:

public ActionResult RemoveQuantityFromProduct(int productId)
{
    Response.CacheControl = "no-cache";
    Response.Cache.SetETag((Guid.NewGuid()).ToString());
    var cart = _workContext.CurrentCustomer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();

    foreach (var sci in cart)
    {
        if (productId.Equals(sci.Id))
        {
            if (sci.Quantity > 1)
            {
                _shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer, sci.Id, sci.Quantity - 1, true);
            }
            else
            {
                _shoppingCartService.DeleteShoppingCartItem(sci, true);
            }
        }
    }

    //updated cart
    cart = _workContext.CurrentCustomer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();
    var model = PrepareShoppingCartModel(new MiniShoppingCartModel(), cart, true);
    return PartialView("AjaxMiniShoppingCart", model);
}
  • Originally the file had build action "compile" wich means the file doesn't exist on the server, but I have now tested with build action "content" to make sure that it really is the same. Still it doesn't work. – Johan Davidsson Oct 10 '11 at 10:09
  • Ok so routeprovider.cs is definitely the same on live and prod and has definitely been copied up to your production server? – WooHoo Oct 10 '11 at 10:35
  • Can you please post your action methods? –  Oct 10 '11 at 10:59
  • I have now added the action method. – Johan Davidsson Oct 10 '11 at 11:55
  • Can you tell me about your production server setup, iis6 or 7. How are you doing your release, manually? – WooHoo Oct 10 '11 at 12:46
  • Production server is windows server 2008 (Webserver edition) with IIS 7.0.6000.16386. I have also tested it on Windows 7 machine with IIS 7.5.7600.16385, also failing. The release is being done with the script from nopCommerce. – Johan Davidsson Oct 10 '11 at 15:08
  • It's been a while since I last installed nopCommerce... so to confirm your making a change locally then your running a nopCommerce script to make that change on your production server? Are you copying the changed code to the prod server manually or publishing it? I'm trying to figure out what's going wrong between building locally and deploying, so any info you can give might help. – WooHoo Oct 10 '11 at 15:56
  • First I do a build in Visual Studio, then I run a batch file wich runs `MSBuild.exe nop.proj` (Provided by nopCommerce). The build can then be found in the folder Deployable. I copy everything from this folder and paste it in the folder wwwroot on the server after deleteing the previous deploy. – Johan Davidsson Oct 10 '11 at 16:51
  • I take it the deploy script runs without any errors? The method RemoveQuantityFromProduct does it have any attributes? Can you email me your Shopping cart controller and the page you added your actionlink to and I will try to duplicate on my local copy. – WooHoo Oct 10 '11 at 17:49
  • Yes, of course! But how do I find your email? – Johan Davidsson Oct 10 '11 at 19:44

3 Answers3

2

My guess is that your routes are different between your local and production servers. On your local machine the route in global.asax.cs is matching the url and routing correctly.

On your production server I don't think its matching the route. So I suggest that you check both local and production are in sync.

If you post your code from RegisterRoutes -> Global.asax.cs might be able to help further (both production and dev).

It might be a typo but in your post the actionlink has removequantityfromproduct but the url you pasted has addquantitytoproduct - two different actions. So it could be that you have a maproute that is incorrectly matching the action removequantityfromproduct and redirecting to addquantitytoproduct.

WooHoo
  • 1,912
  • 17
  • 22
2

The answer to this one was quite simple... I built the solution in release mode, but for some reason the script for deploying took some code from the debug folder instead, that is why the routing was incorrect...

1
@Ajax.ActionLink("-",
            "RemoveQuantityFromProduct",
            "ShoppingCart",
            new { productId = item.Id.ToString() },
            new AjaxOptions
            {
                UpdateTargetId = "AjaxMiniShoppingCart",
                HttpMethod = "POST",
                InsertionMode = InsertionMode.Replace,
                OnSuccess="toggleCart",
            }, null)

Try setting HTML attributes to null.

  • Unfortunately this didn't help. The links are still different on the local computer and the server, and the links still don't work on the server. – Johan Davidsson Oct 10 '11 at 08:50