2008-10-01 317 views
87

我有一个动作方法的控制器如下:ASP.NET MVC - 传递参数给控制器

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

当我运行它,我得到一个错误,指出:

参数字典不包含参数'firstItem'的'System.Int32'类型的有效值。要使参数可选,其类型应该是引用类型或Nullable类型。

我曾经在一个点工作,我决定尝试没有参数的功能。发现控制器不是持久的,我把参数放回去,现在当我调用该方法时,它拒绝识别参数。

我使用此URL语法来调用的行动:

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

任何想法,为什么我会得到这个错误,我需要做什么来解决这个问题呢?

我试着添加另一种方法,它采用一个整数的类,它也失败了同样的原因。我试着添加一个接受一个字符串,并将该字符串设置为空。我尝试添加一个没有参数,并且工作正常,但当然它不适合我的需要。

回答

94

您的路由需要按照{controller}/{action}/{firstItem}的方向设置。如果您在文件中将路由保留为默认{controller}/{action}/{id},则需要传入id

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

...或者与之相近的东西。

+37

或者只是将“firstItem”重命名为“id” – 2009-02-06 16:01:54

+8

另外,向MapRoute添加一个约束对象是明智的选择,如下所示:`new {firstItem = @“\ d”}`。这样它将**仅接受参数是否为任何类型的数字。您可以随意修改正则表达式,甚至限制小数位数,如下所示:`new {firstItem = @“\ d {4}”}` - 现在只能有4个数字。编辑:完全修改MapRoute的示例:http://jsfiddle.net/HJRgT/ – KristianB 2011-09-18 16:57:35

15

要改写Jarret Meyer's answer,您需要将参数名称更改为“身份证”或添加像这样的路线:

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

的原因是默认路由仅查找不带参数或称为参数行动'ID'。

编辑:heh,nevermind Jarret在发布后添加了一个路由示例。

0

或者,您可以尝试将参数类型更改为字符串,然后将该字符串转换为方法中的整数。我是MVC的新手,但我相信你需要在你的参数列表中可为空的对象,控制器还会指出没有提供这样的参数?所以......

public ActionResult ViewNextItem(string id)... 
7

public ActionResult ViewNextItem(int? id)使得id整数可空类型,不需要串< - > INT转换。

1

还有另一种方式来实现这一目标(更详细的斯蒂芬·瓦尔特描述Pager example

本质上讲,你在视图中创建一个链接:

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

在的RouteData你可以指定名称/值对(例如routeData [“page”] = 5),并在控制器的Index函数中获取相应的参数值。也就是说,

public ViewResult Index(int? page) 

将有页面为5。我不得不承认过去了,这是相当不寻常的字符串(“页”)自动地成为一个变量 - 但这是MVC是如何工作的其他语言。 ..

74

你可以改变对与firstItem ID和它的工作

你可以改变在Global.asax中路由(我不推荐这)

,并不能相信没有人提到这个,你可以拨打:

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

在@ Url.Action是:

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

取决于你在做什么,最后将是更适合的类型。 另外,您应该考虑不要执行ViewStockNext操作,而应该考虑带有索引的ViewStock操作。 (我的2cents)

+4

这正是我正在寻找:) thx – sasjaq 2012-07-09 21:17:24

0

“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" }); 
7

源泉创造了一个很好的库,它允许你添加别名你的参数在动作属性上。这看起来像这样:

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

有了这个,你不必改变你的路由只是为了处理不同的参数名称。该库也支持多次应用,因此您可以映射多个参数拼写(重构时非常方便,而不会破坏公共界面)。

您可以从Nuget得到它,并与路由属性就可以了here

3

读杰弗里巴勒莫的文章或做它:

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

使用ASP.NET核心标签辅助功能:

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