ASP.NET MVC ActionLink not picking the correct controller
Question:
I am trying to pass a variable - in this case the int variable 'productId' in the url for the controller and the action method specified in the ActionLink method.
Problem:
My routes are set up like this:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Login", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "ProductDetailHandler",
url: "{controller}/{action}/{productId}",
defaults: new { controller = "Product", action = "ProductDetail", productId = UrlParameter.Optional }
);
My "ActionLink" in my "Products.cshtml" view that is returned by the "HomePageController" is set like this:
@Html.ActionLink("Product", "ProductDetail", new { productId = (ViewBag.data as List<LoginTest.Models.HomePageItem>).First().Id })
The controller that receives the passed "productId" along with its action is set as follows:
public class ProductController : Controller
{
public ActionResult ProductDetail(int productId)
{
//logic
return View();
}
}
This is a problem when viewing the url shown to be redirected to the HomePage controller:
If someone can tell me why my ActionLink doesn't fit the Product controller , that would be great.
EDIT:
This is the "Home" view that I click on the button to redirect me to " product / productDetail / productId "
My route now only has a "Default Example":
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Login", id = UrlParameter.Optional }
);
Action link now:
@Html.ActionLink("Product", "ProductDetail", "Product", new { id = (ViewBag.data as List<LoginTest.Models.HomePageItem>).First().Id })
The controller and action method "Product / ProductDetail" now looks like this:
public class ProductController : Controller
{
public ActionResult ProductDetail(int id)
{
string hold;
return View();
}
}
This still gives me the wrong url as shown, notice that "productId" is now displayed as "length"?
source to share
Since the link is on the page being rendered HomePageController
, this controller in the route is used by default. You need to use an overload that takes a controller name
@Html.ActionLink("Your link text", "ProductDetail", "Product", new { id = 1 }, null)
As a side note, your original route table would create /Product/ProductDetail?productId =1
with this overload as it matches the default route, which is the first route in your table (the order of the routes is important). To have /Product/ProductDetail/1
, either change the order of the routes, or just change the parameter ProductDetail
to int id
rather thanint productId
source to share
Try the following:
routes.MapRoute(
name: "ProductDetailHandler",
url: "Product/{action}/{productId}",
defaults: new { controller = "Product", action = "ProductDetail", productId = UrlParameter.Optional }
);
routes.MapRoute
(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Not sure what you are trying to do with the login controller. Perhaps you can enter login to your home page or redirect Home / Index to Login.
Also you can specify the default namespace if it doesn't find your controller:
routes.MapRoute(
name: "ProductDetailHandler",
url: "Product/{action}/{productId}",
defaults: new { controller = "Product", action = "ProductDetail", productId = UrlParameter.Optional },
new string[] { "MyProject.Controllers" }
);
routes.MapRoute
(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MyProject.Controllers" }
);
source to share