Reputation: 880
I have an area named adpan in my mvc site with following route config:
context.MapRoute(
"adpan_clinics",
"adpan/DoctorClinics/{doctorObj}/{controller}/{action}/{clinicObj}",
new { action = "Index", Controller = "Clinics", clinicObj = UrlParameter.Optional }
);
context.MapRoute(
"adpan_default",
"adpan/{controller}/{action}/{obj}",
new { action = "Index", Controller = "Dashboard", obj = UrlParameter.Optional }
);
I use T4MVC for routing. Everything works fine until I want to route back from adpan_clinics to adpan_default using action link.
Scenario) I have following urls:
1st url) http://localhost/adpan/Doctors/Index
2nd url) http://localhost/adpan/DoctorClinics/doctor1/Clinics/index
I can redirect to 2nd url with an action link on 1st url's view like this:
@Html.ActionLink("Manage Clinics", MVC.adpan.Clinics.Index().AddRouteValues(new { doctorObj = item.Url }))
But, when redirecting back to 1st url using following action link, I face url appending problem:
@Html.ActionLink("Back to Doctors", MVC.adpan.Doctors.Index())
This action link gives me the following bad url instead of 1st url(Although the page loads correctly!):
bad url) http://localhost/adpan/DoctorClinics/doctor1/Doctors
NOTE: I've also tried this without T4MVC and specifying null values in action link parameters as follow, but still getting the bad url:
@Html.ActionLink("Back to Doctors", "Index", "Doctors", null, null)
I'm just working in adpan area with 2 routes.
I would appreciate any solution and if possible, the reason for getting the correct view from that bad url.
Upvotes: 0
Views: 478
Reputation: 880
Based on @NightOwl888 answer and difference between RouteLink and ActionLink, I found the solution for both hard-coded approach and T4MVC approach.
1) Hard-Coded approach: route name must be specified:
//signiture: RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues);
@Html.RouteLink("Back to Doctors","adpan_default", new { controller = "Doctors", action = "Index"})
resulting url: http://localhost/adpan/Doctors
2) T4MVC approach: route name must be specified:
//signiture: RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, ActionResult result, IDictionary<string, object> htmlAttributes)
@Html.RouteLink("Back to Doctors","adpan_default", MVC.adpan.Doctors.Index().AddRouteValues(new {Area=""}), null)
resulting url: http://localhost/adpan/Doctors
Why AddRouteValues(new {Area=""}) ?
Due to the discussion here, it seems like a bug in T4MVC. Below route link adds ?Area=adpan as a futile parameter to the url:
@Html.RouteLink("Back to Doctors", "adpan_default", MVC.adpan.Doctors.Index(), null)
resulting url: http://localhost/adpan/Doctors?Area=adpan
However, this can be a trick to cheat over unwanted url parameters in T4MVC.
Upvotes: 0
Reputation: 56849
Route values are supplied not just from the parameters of ActionLink
, but will also bleed over from the current request. While many people don't find this intuitive, it makes it really easy to do things like stay within the current culture or area of the site.
Route values are not for meta data. They are the values that will be used when matching a URL pattern or to determine which route to use to build the outgoing URL. I suspect that is what you are grappling with, because it is very unusual to set a route value to a URL.
If you need to pass meta-data along with route information, there is a DataTokens
property that is meant for that purpose. While both are passed through the request, only route values are used to determine whether the route matches.
It is also possible to override the route values from the current request by specifying them explicitly.
@Html.RouteLink("foobar", new { controller = "Home", action = "Index", doctorObj = "" })
But since you would need to do that on every affected link, it is much more practical to keep the invalid data out of the route values in the first place.
Upvotes: 1