ASP.NET MVC - передача параметров контроллеру

У меня есть контроллер с методом действия следующим образом:

public class InventoryController : Controller
{
    public ActionResult ViewStockNext(int firstItem)
    {
        // Do some stuff
    }
}

И когда я запускаю его, я получаю сообщение об ошибке:

Словарь параметров не содержит допустимого значения типа System.Int32 для параметра firstItem. Чтобы сделать параметр необязательным, его тип должен быть либо ссылочным, либо Nullable.

Однажды у меня это работало, и я решил попробовать функцию без параметров. Обнаружив, что контроллер не был постоянным, я вернул параметр, теперь он отказывается распознавать параметр, когда я вызываю метод.

Я использую этот синтаксис URL для вызова действия:

http://localhost:2316/Inventory/ViewStockNext/11

Есть идеи, почему я получаю эту ошибку и что мне нужно сделать, чтобы ее исправить?

Я попытался добавить еще один метод, который принимает целое число в класс, но он также не работает по той же причине. Я пробовал добавить тот, который принимает строку, и для этой строки установлено значение null. Я пробовал добавить один без параметров, и он отлично работает, но, конечно, мне это не подходит.


person Odd    schedule 01.10.2008    source источник


Ответы (10)


Ваша маршрутизация должна быть настроена в соответствии со строками {controller}/{action}/{firstItem}. Если вы оставили маршрутизацию по умолчанию {controller}/{action}/{id} в вашем global.asax.cs файле, вам нужно будет передать id.

routes.MapRoute(
    "Inventory",
    "Inventory/{action}/{firstItem}",
    new { controller = "Inventory", action = "ListAll", firstItem = "" }
);

... или что-то близкое к этому.

person Jarrett Meyer    schedule 01.10.2008
comment
Или просто переименуйте firstItem в id - person Kyle Trauberman; 06.02.2009
comment
Кроме того, было бы разумно добавить объект ограничений в MapRoute, например: new { firstItem = @"\d" }. Таким образом, он будет только принят, если параметр представляет собой любое число. Вы можете изменить регулярное выражение по своему усмотрению и даже ограничить количество десятичных знаков, например: new { firstItem = @"\d{4}" } - теперь оно может состоять только из 4 чисел. Изменить: пример полностью измененного MapRoute: jsfiddle.net/HJRgT - person KristianB; 18.09.2011

вы можете изменить firstItem на id, и он будет работать

вы можете изменить маршрутизацию на global.asax (я не рекомендую это)

и, не могу поверить, что никто об этом не упомянул, вы можете позвонить:

http://localhost:2316/Inventory/ViewStockNext?firstItem=11

В @ Url.Action будет:

@Url.Action("ViewStockNext", "Inventory", new {firstItem=11});

в зависимости от того, чем вы занимаетесь, последний будет более подходящим. Также вам следует подумать о том, чтобы не выполнять действие ViewStockNext, а вместо этого выполнять действие ViewStock с index. (мои 2 цента)

person Bart Calixto    schedule 02.12.2011

Чтобы перефразировать ответ Джаррета Мейера, вам необходимо изменить укажите имя параметра в 'id' или добавьте такой маршрут:

routes.MapRoute(
        "ViewStockNext", // Route name
        "Inventory/ViewStockNext/{firstItem}",  // URL with parameters
        new { controller = "Inventory", action = "ViewStockNext" }  // Parameter defaults
    );

Причина в том, что маршрут по умолчанию ищет только действия без параметра или параметр с именем «id».

Изменить: Хех, неважно, что Джаррет добавил пример маршрута после публикации.

person Matt Mitchell    schedule 01.10.2008

или сделайте это с помощью атрибута маршрута:

public class InventoryController : Controller
{
    [Route("whatever/{firstItem}")]
    public ActionResult ViewStockNext(int firstItem)
    {
        int yourNewVariable = firstItem;
        // ...
    }
}
person Yar    schedule 28.08.2015
comment
Это свойство может не работать со старыми версиями MVC. - person Suat Atan PhD; 01.06.2017
comment
Кроме того, чтобы это сработало, вам необходимо убедиться, что вы вызвали routes.MapMvcAttributeRoutes(); в RegisterRoutes(RouteCollection) методе приложения (обычно в шаблоне App_Start \ RouteConfig.cs). По умолчанию его там может не быть. - person Daniel Scott; 15.12.2019

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

[ParameterAlias("firstItem", "id", Order = 3)]
public ActionResult ViewStockNext(int firstItem)
{
    // Do some stuff
}

При этом вам не нужно изменять свою маршрутизацию только для обработки другого имени параметра. Библиотека также поддерживает его многократное применение, поэтому вы можете сопоставить несколько вариантов написания параметров (удобно при рефакторинге без нарушения общедоступного интерфейса).

Вы можете получить его на Nuget и прочитать об этом статью Джеффри Палермо здесь

person Matthew Nichols    schedule 12.09.2012

public ActionResult ViewNextItem(int? id) делает id целочисленным типом, допускающим значение NULL, без необходимости преобразования строки ‹-> int.

person Oskar Duveborn    schedule 25.01.2009

Использование вспомогательной функции тегов ASP.NET Core:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>
person Sasha Yakobchuk    schedule 04.04.2017
comment
По иронии судьбы, самый короткий ответ - лучший (этот). - person ; 06.06.2019

Есть еще один способ добиться этого (более подробно описанный в статье Стивена Вальтера Пример пейджера

По сути, вы создаете ссылку в представлении:

Html.ActionLink("Next page", "Index", routeData)

В routeData вы можете указать пары имя / значение (например, routeData ["page"] = 5), а в функции Index контроллера соответствующие параметры получают значение. То есть,

public ViewResult Index(int? page)

будет передано page как 5. Я должен признать, что довольно необычно, что строка ("страница") автоматически становится переменной - но так MVC работает и на других языках ...

person Felix    schedule 11.10.2009

Причина особого обращения с «id» заключается в том, что он добавляется к сопоставлению маршрутов по умолчанию. Чтобы изменить это, перейдите в Global.asax.cs, и вы найдете следующую строку:

routes.MapRoute ("Default", "{controller}/{action}/{id}", 
                 new { controller = "Home", action = "Index", id = "" });

Измените его на:

routes.MapRoute ("Default", "{controller}/{action}", 
                 new { controller = "Home", action = "Index" });
person Aristoteles    schedule 19.01.2012

Или вы можете попробовать изменить тип параметра на строку, а затем преобразовать строку в целое число в методе. Я новичок в MVC, но считаю, что вам нужны объекты, допускающие значение NULL, в вашем списке параметров, как еще контроллер укажет, что такой параметр не был предоставлен? Так...

public ActionResult ViewNextItem(string id)...
person RAL    schedule 10.12.2008