ActionLink для отображения параметров в URL вместо строки запроса?

Я определил этот маршрут:

routes.MapRoute(
                   "Details", // Route name
                   "{home}/{details}/{id}/{name}", // URL with parameters
                   new
                   {
                       controller = "Home",
                       action = "Details",
                       id = UrlParameter.Optional,
                       name = UrlParameter.Optional
                   } // Parameter defaults
               );

ActionLink:

 @Html.ActionLink("Show Details", "Details", "MyController", new { id = 1, name ="a" })

Результат actionlink в /Home/Details/1?name=a Я после /Home/List/1/a

Ответ 1

Ваше определение маршрута должно быть таким:

routes.MapRoute(
    "Details", // Route name
    "{controller}/{action}/{id}/{name}", // URL with parameters
    new
    {
        controller = "Home",
        action = "Details",
        id = UrlParameter.Optional,
        name = UrlParameter.Optional
    } // Parameter defaults
);

Также вы должны использовать надлежащую перегрузку:

@Html.ActionLink(
    "Show Details",             // linkText
    "Details",                  // action
    "MyController",             // controller
    new { id = 1, name = "a" }, // routeValues
    null                        // htmlAttributes
)

Обратите внимание на null в конце.

Ответ 2

Дикое предположение:

Вероятно, ваш маршрут был зарегистрирован после маршрута по умолчанию. Поместите это как первый маршрут внутри вашего global.asax, тогда он будет работать.

Как ниже:

    public static void RegisterRoutes(RouteCollection routes) {

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
                           "Details", // Route name
                           //Put action instead of details
                           "{home}/{action}/{id}/{name}", // URL with parameters
                           new
                           {
                               controller = "Home",
                               action = "Details",
                               id = UrlParameter.Optional,
                               name = UrlParameter.Optional
                           } // Parameter defaults
                       );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

UPDATE

@Simon правильно, но вы можете использовать другой способ, если хотите.

Чтобы маршрут работал только для одного действия, используйте следующий код.

Создайте ограничение следующим образом:

public class EqualConstraint : IRouteConstraint {

    private string _match = String.Empty;

    public EqualConstraint(string match) {

        _match = match;
    }

    public bool Match(System.Web.HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {

        return string.Equals(values[parameterName].ToString(), _match);
    }
}

И затем измените свой маршрут, как показано ниже:

    routes.MapRoute(
                       "Details", // Route name
                       //Put action instead of details
                       "{home}/{action}/{id}/{name}", // URL with parameters
                       new
                       {
                           controller = "Home",
                           action = "Details",
                           id = UrlParameter.Optional,
                           name = UrlParameter.Optional
                       }, // Parameter defaults
                       new { 
                          controller = new EqualConstraint("Home"),
                          action = new EqualConstraint("Details")
                       }
                   );