When Urls are autogenerated using the Url.Action
helper, if a page contains a line similar to
@Url.Action("Edit","Student")
is expected to generate a url like domain/student/edit
and its working as expected.
But if the requested url contains some parameters, like domain/student/edit/210
, the above code uses these parameters from the previous request and generates something similar even though I've not provided any such parameter to the Action
method.
In short, if the requested url contains any parameters, any auto generated links of the page (served for that request) will include those parameters as well no matter if I specify them or not in the Url.Action
method.
What's going wrong?
Weird, can't seem to reproduce the problem:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
public ActionResult About(string id)
{
return View();
}
}
and inside Index.cshtml
:
@Url.Action("About", "Home")
Now when I request /home/index/123
the url helper generates /home/about
as expected. No ghost parameters. So how does your scenario differs?
UPDATE:
Now that you have clarified your scenario it seems that you have the following:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
}
and inside Index.cshtml
you are trying to use:
@Url.Action("Index", "Home")
If you request /home/index/123
this generates /home/index/123
instead of the expected /home/index
(or simply /
taken into account default values).
This behavior is by design. If you want to change it you will have to write your own helper which ignores the current route data. Here's how it might look:
@UrlHelper.GenerateUrl(
"Default",
"index",
"home",
null,
Url.RouteCollection,
// That's the important part and it is where we kill the current RouteData
new RequestContext(Html.ViewContext.HttpContext, new RouteData()),
false
)
This will generate the proper url you were expecting. Of course this is ugly. I would recommend you encapsulating it into a reusable helper.
Use Darin's answer from this similar question.
@Url.Action("Edit","Student", new { ID = "" })
Use ActionLink overload that uses parameters and supply null
You could register custom route for this action for example:
routes.MapRoute("Domain_EditStudentDefault",
"student/edit",
new {
controller = MVC.Student.Name,
action = MVC.Student.ActionNames.Edit,
ID = UrlParameter.Optional
},
new object(),
new[] { "MySolution.Web.Controllers" }
);
you then could use url.RouteUrl("Domain_EditStudentDefault")
url RouteUrl helper override with only routeName
parameter which generates url without parameters.