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. Я попытался добавить один без параметров, и это работает отлично, но, конечно, это не устраивает моих потребностей.

Ответ 1

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

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

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

Ответ 2

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

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

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

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

В @Url.Action будет:

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

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

Ответ 3

Чтобы перефразировать ответ Jarret Meyer, вам нужно изменить имя параметра на 'id' или добавить маршрут следующим образом:

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

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

Редактировать: Хех, никогда. Яррет добавил пример маршрута после публикации.

Ответ 4

public ActionResult ViewNextItem(int? id) делает id целочисленным тип с нулевым значением, не нужно преобразовывать строки ↔ int.

Ответ 5

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

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

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

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

Ответ 6

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

public class InventoryController : Controller
{
    [Route(whatever/{firstItem})]
    public ActionResult ViewStockNext(int firstItem)
    {
        int yourNewVariable = firstItem;
        // ...
    }
}

Ответ 7

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

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

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

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

public ViewResult Index(int? page)

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

Ответ 8

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

public ActionResult ViewNextItem(string id)...

Ответ 9

Причиной особого обращения с "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" });

Ответ 10

Использование функции ASP.NET Core Tag Helper:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>