开发者

Html.ActionLink rendering non-route URL

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜