ajax.actionlink shows different urls on server and visual studio - asp.net-mvc-3

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);
}

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.

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

#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.

Related

Can't find Controller in MVC 3 project - NotFound error

I have this global.asax file with this code:
routes.MapRoute("Invitations",
"api/invitations",
new { controller = "Invitations", action = "Invitation"});
And I have a Controller:
public class InvitationsController : Controller
{
[HttpPut]
public JsonResult Invitation(InvitationResponse invitationResponse)
{
//code
}
}
And I'm accessing the controllers by HttpWebRequest with this URL:
"http://localhost:6055/API/Invitations"
When I run this I get the error "NotFound".
EDIT:
The whole global route:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Users",
"api/users/{id}",
new { controller = "Users", action = "UserAction", id = UrlParameter.Optional });
routes.MapRoute("CheckIn",
"api/checkins",
new { controller = "CheckIn", action = "CheckIn" });
routes.MapRoute("Appointments",
"api/appointments/{id}",
new { controller = "Appointments", action = "Appointment", id = UrlParameter.Optional });
routes.MapRoute("UserAppointments",
"api/users/{userId}/appointments/{startDate}",
new { controller = "Appointments", action = "UserAppointments", startDate = UrlParameter.Optional });
routes.MapRoute("UserInvitations",
"api/users/{userId}/invitations",
new { controller = "Invitations", action = "UserInvitations" });
routes.MapRoute("UserOverview",
"api/users/{id}/overview",
new { controller = "Users", action = "Overview" });
routes.MapRoute("Invitations",
"api/invitations",
new { controller = "Invitations", action = "Invitation"});
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
"http://localhost:6055/API/Invitations" doesn't look correct, shouldn't it be
"http://localhost:6055/YourApp/API/Invitations"

Paging/Sorting not working on web grid used in Partial View

I have a partial view where I am showing a web grid depending upon a value selected from a page.
For drop down I have used
#Html.DropDownListFor(
x => x.ItemId,
new SelectList(Model.Items, "Value", "Text"),
new {
id = "myddl",
data_url = Url.Action("Foo", "SomeController")
}
)
For drop down item select I have used
$(function() {
$('#myddl').change(function() {
var url = $(this).data('url');
var value = $(this).val();
$('#result').load(url, { value: value })
});
});
and below is my action
public ActionResult Foo(string value)
{
SomeModel model = ...
return PartialView(model);
}
everything works good, but when I try doing a paging or sorting on my webgrid which is on my partial view I am showing a new window with the web grid.
I wanted to be able to sort and page on the same page without postback
Please help
The following example works fine for me.
Model:
public class MyViewModel
{
public string Bar { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Foo(string value)
{
var model = Enumerable.Range(1, 45).Select(x => new MyViewModel
{
Bar = "bar " + value + " " + x
});
return PartialView(model);
}
}
Index.cshtml view:
<script type="text/javascript">
$(function () {
$('#myddl').change(function () {
var url = $(this).data('url');
var value = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { value: value },
success: function (result) {
$('#result').html(result);
}
});
});
});
</script>
#Html.DropDownList(
"id",
new[] {
new SelectListItem { Value = "val1", Text = "value 1" },
new SelectListItem { Value = "val2", Text = "value 2" },
new SelectListItem { Value = "val3", Text = "value 3" },
},
new {
id = "myddl",
data_url = Url.Action("Foo", "Home")
}
)
<div id="result">
#Html.Action("Foo")
</div>
Foo.cshtml partial:
#model IEnumerable<MyViewModel>
#{
var grid = new WebGrid(
canPage: true,
rowsPerPage: 10,
canSort: true,
ajaxUpdateContainerId: "grid"
);
grid.Bind(Model, rowCount: Model.Count());
grid.Pager(WebGridPagerModes.All);
}
#grid.GetHtml(
htmlAttributes: new { id = "grid" },
columns: grid.Columns(
grid.Column("Bar")
)
)
Notice that I have used a GET request to refresh the grid instead of POST because this way the value query string parameter selected in the dropdown is preserved for future sorting and paging.

MVC3 Routing Not Found

Any idea why this link is not found?
context.MapRoute(null, "Admin/CompanyUserDelete/{userprofileid}", new { controller = "Admin", action = "CompanyUserDelete", userprofileid = UrlParameter.Optional });
It is definded using the AreaRegistration class.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(null, "Admin", new { controller = "Admin", action = "Index" });
context.MapRoute(null, "Admin/Users", new { controller = "Admin", action = "CompanyUsers" });
context.MapRoute(null, "Admin/Users/Create", new { controller = "Admin", action = "CreateUser" });
context.MapRoute(null, "Admin/Users/{userprofileid}", new { controller = "Admin", action = "CompanyUser" });
context.MapRoute(null, "Admin/CompanyUserDelete/{userprofileid}", new { controller = "Admin", action = "CompanyUserDelete", userprofileid = UrlParameter.Optional });
context.MapRoute(null, "Admin/Users/{userprofileid}/Photo", new { contro
ller = "Admin", action = "UserImage" });
}
</code></pre>
Here is the link not found.
#Html.ActionLink("Delete", "CompanyUserDelete", "Admin", new { area = "Admin", userprofileid = userItem.UserProfileId }, null)
CompanyUserDelete doesn't declare the first parameter "area" you are sending over to it.
context.MapRoute(null, "Admin/CompanyUserDelete/{userprofileid}", new { controller = "Admin", action = "CompanyUserDelete", userprofileid = UrlParameter.Optional });
but here you have "area"
#Html.ActionLink("Delete", "CompanyUserDelete", "Admin", new { area = "Admin", userprofileid = userItem.UserProfileId }, null)

Passing routeValues to Controller in MVC 3

i have this code in View
#using (Html.BeginForm())
{
#: Location #Html.DropDownList("territryID", (SelectList)ViewBag.Territory, "choose one")
#Ajax.ActionLink(
"ok",
"Info", new { territryID = "#territryID" },
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "post1"
})
<div id="post1">
</div>
}
and this code in my Controller
[HttpPost]
public ActionResult Info(int? territryID)
{
if (territryID == null)
{
return RedirectToAction("Info");
}
var model = (from c in _db.OCRDs
where c.Territory == territryID
select c).Distinct();
return PartialView("_getCustomerByTerritory", model);
}
how to passing my dropdownlist selected value to territryID parameter in controller, how to do that?
thanks,
erick
How about this, initialize your URL to something like this (also note the assignment of an id to the link):
#Ajax.ActionLink("ok", "Info", new { territryID = "REPLACEME" }, new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", UpdateTargetId = "post1" }, new { id = "oklink" })
Replace the placeholder (REPLACEME) when the dropdown changes, like so:
<script>
$('#territryID').change(function () {
var newid = $('#territryID').val();
var oldLink = $('#oklink').attr('href');
var newLink = oldLink.replace('REPLACEME', newid);
$('#oklink').attr('href', newLink);
});
</script>

Routing does not work in my asp.net app

I have 4 routes defined 5 different urls. Tested a lot with RouteDebugger but can not solve.
The problem is that Top 2 links always use {controller}/{action}/{id} this route which is root1 and can not redirect to proper pages.
Links
#Html.ActionLink("Go Index by name", "Page", "Home", new { name="contact"}, null)
#Html.ActionLink("Go Index by id", "Index", "Admin", new { id=2}, null)
#Html.ActionLink("Go Index by id and name", "Page", "Home", new { name = "contact", id = 2 }, null)
#Html.ActionLink("Root Admin", "Index", "Admin")
#Html.ActionLink("Root", "Index", "Home")
Here is the Map.Route
routes.MapRoute("root1",
"{controller}/{action}/{id}",
new { controller = "Admin", action = "Index" });
routes.MapRoute("root2",
"{controller}/{action}/{name}",
new { controller = "Home", action = "Page" });
routes.MapRoute("root3",
"{controller}/{action}/{name}/{id}",
new { controller = "Home", action = "Page" });
routes.MapRoute("root4",
"{controller}/{action}/{name}",
new { controller = "Home", action = "Index", name = UrlParameter.Optional });
These are the routes I have set up and it seems to hit each one correctly.
Note that root3 has been moved to the top since root2 will match that as well. also, the validation for root1 with id as King Julian suggested
The route:
#Html.ActionLink("Root Admin", "Index", "Admin")
should not match root1 nor root2 since there is no default for id and name respectively in the route definition
routes.MapRoute("root3",
"{controller}/{action}/{name}/{id}",
new { controller = "Home", action = "Page" });
routes.MapRoute("root1",
"{controller}/{action}/{id}",
new { controller = "Admin", action = "Index" },
new { id = #"\d+" });
routes.MapRoute("root2",
"{controller}/{action}/{name}",
new { controller = "Home", action = "Page" });
routes.MapRoute("root4",
"{controller}/{action}/{name}",
new { controller = "Home", action = "Index", name = UrlParameter.Optional
});
Add constraints to your routes. For example:
routes.MapRoute(
"root1",
"{controller}/{action}/{id}",
new { controller = "Admin", action = "Index" },
new {id = #"\d+" }
);
Will ensure that root1 only matches when id is an integer. Otherwise, root2 would catch it.

Resources