Использование Html.ActionLink с RouteValues

У меня есть следующий Html:

<%: Html.ActionLink(item.ProductName, "Details", "Product", new { item.ProductId }, null)%>

Это отображается как:

<a href="/Product/Details?ProductId=1">My Product Name</a>

Однако, когда я нажимаю на это, я получаю следующую ошибку:

Словарь параметров содержит нулевую запись для параметра 'id' of non-nullable тип 'System.Int32' для метода 'System.Web.Mvc.ActionResult Details (Int32)' в 'MyProject.Controllers.ProductController. Необязательный параметр должен быть ссылочным типом, нулевым типом или быть объявлен как необязательный параметр.

Имя параметра: параметры

Похоже, что моя маршрутизация не похожа на строку запроса "? ProductId = 1".

Если я использую вместо этого:

<%: Html.ActionLink(item.ProductName, string.Format("Details/{0}", item.ProductId), "Product", null, null)%>

Я получаю следующую ссылку:

<a href="/Product/Details/1">My Product Name</a>

... и это работает правильно при нажатии.

Я пропустил что-то основное здесь? Я хотел бы использовать RouteValues, но я не понимаю, почему эта ошибка возникает. Как я могу заставить мой метод контроллера принимать параметры строки запроса?

Единственное отображение маршрута, которое у меня есть:

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

Ответ 1

Измените параметр действия, чтобы быть int ProductId.

public ActionResult Details(int productId)
{
    return View("");
}

ваш контроллер должен получить параметр "id", потому что вы объявили его как не nullable int, поэтому, когда вы отправляете productId, он все еще не соответствует сигнатуре функции.
если вы не укажете имя параметра, значения по умолчанию в global.asax измените имя параметра на id:

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

см. последнюю строку.

Ответ 2

Вы устанавливаете символ / как разделители между контроллером, действием и идентификатором (параметры), если вы вызываете URL-адрес, например /Product/Details?ProductId=1, вызываете контроллер Product, но действие с текстом Details?ProductId=1, а затем маршрутизация не получит следующий /.