This is probably stupid, but I can't seem to figure it out. I'm using Html.ActionLink
to create links between master and child pages: Employees -> Employee
.
I just noticed that the URL it's rendering is not "shaped" as the route it's supposed to match. For example the URL being generated is /Employee?EmployeeId=?
when it's supposed to be /Employees/{EmployeeId}
.
Am I missing something that's supposed to make it return that kind of a url? I was hand writing all the links up until 2 weeks ago when I switched to Html.ActionLink
and I could have sworn it was working properly, but now I see this pattern everywhere on my app and I don't like it...
Url.Action
and Html.RouteLink
create the same URL as well.
Help would be appreciated.
UPDATE for @Darin
Here's how the route is registered:
Routes.MapRoute("QbNn7GFjJZBzYED7", Settings.EmployeeRoute, new {
action = "Employee"
}, new {
controller = new ControllerConstraint(Settings.AdministrationController),
group = new GroupConstraint(Settings.CorporateGroup),
EmployeeId = @"\d+"
});
Settings.EmployeeRoute = "{controller}/{group}/Employees/{EmployeeId}";
Settings.AdministrationController = "Administration";
Settings.CorporateGroup = "Corporate";
And before you ask why the route name is QbNn7GFjJZBzYED7
, it's becau开发者_如何学编程se I got tired of giving the routes names and because I never refer to the routes by their name, so I just started generating random strings to fill in the void.
UPDATE 2
The two constraints were essentially the same with different names. Thus, I merged it into one and here's what it looks like:
internal class NameConstraint : IRouteConstraint {
private readonly string[] Names = new string[0];
public NameConstraint(
string Name) {
this.Names = new string[1] {
Name.ToLower()
};
}
public NameConstraint(
string[] Names) {
this.Names = Names.Select(
n =>
(n.ToLower())).ToArray();
}
public bool Match(
HttpContextBase HttpContextBase,
Route Route,
string Paramater,
RouteValueDictionary RouteValueDictionary,
RouteDirection RouteDirection) {
string Param = ((string)RouteValueDictionary[Paramater]).ToLower();
return this.Names.Contains(Param);
}
}
Now, between this update and the previous one, the routes fixed themselves. The only change that happened was taking ControllerConstraint
and GroupConstraint
and merging them into NameConstraint
and the subsequent rebuild.
How it decided to fix itself, I don't know, but it did. I don't think it was the merger of the constraints, and I doubt it was the rebuild.
Now both of these are generating the right routes:
Html.ActionLink(Employee.Name, "Employee", new { EmployeeId = Employee.EmployeeId })
Html.ActionLink(Employee.Name, "Employee", "Administration", new { group = "Corporate", EmployeeId = Employee.EmployeeId }, null)
In the end I'm not sure what the actual fix was...
If your route looks like this: {controller}/{group}/Employees/{EmployeeId}
routes.MapRoute(
"CustomRoute",
"{controller}/{group}/Employees/{EmployeeId}",
new {
controller = "Foo",
action = "Bar",
EmployeeId = UrlParameter.Optional
}
);
in order to generate an action link matching this route you need this:
<%= Html.ActionLink(
"some text", // link text
"Bar", // action
"Foo", // controller
new { group = "123", EmployeeId = "456" }, // route values
null // html attributes
) %>
Things to note:
- Your route definition doesn't contain an
{action}
placeholder meaning that you need to specify the action exactly as the default value in your route. - The
group
parameter should be specified. It cannot be optional because it is not at the end of the route
精彩评论