ASP.NET MVC - 将参数传递给控制器
Posted
技术标签:
【中文标题】ASP.NET MVC - 将参数传递给控制器【英文标题】:ASP.NET MVC - passing parameters to the controller 【发布时间】:2010-09-14 10:15:14 【问题描述】:我有一个控制器,其动作方法如下:
public class InventoryController : Controller
public ActionResult ViewStockNext(int firstItem)
// Do some stuff
当我运行它时,我收到一条错误消息:
参数字典不包含参数“firstItem”的“System.Int32”类型的有效值。要使参数可选,其类型应该是引用类型或 Nullable 类型。
我让它在某一时刻工作,我决定尝试不带参数的函数。发现控制器不是持久的,我把参数放回去了,现在当我调用方法时它拒绝识别参数。
我正在使用这个 url 语法来调用操作:
http://localhost:2316/Inventory/ViewStockNext/11
任何想法为什么我会收到此错误以及我需要做些什么来修复它?
我尝试向类添加另一个采用整数的方法,它也因同样的原因而失败。我尝试添加一个带字符串的字符串,并将字符串设置为空。我试过添加一个不带参数的,效果很好,但它当然不适合我的需要。
【问题讨论】:
【参考方案1】:您的路由需要按照controller/action/firstItem
进行设置。如果您在global.asax.cs
文件中将路由保留为默认controller/action/id
,则需要传入id
。
routes.MapRoute(
"Inventory",
"Inventory/action/firstItem",
new controller = "Inventory", action = "ListAll", firstItem = ""
);
...或类似的东西。
【讨论】:
或者只是将“firstItem”重命名为“id” 另外,将约束对象添加到 MapRoute 是明智之举,如下所示:new firstItem = @"\d"
。这样,如果参数是任何类型的数字,它将仅接受。您可以随意修改正则表达式,甚至限制小数位数,如下所示:new firstItem = @"\d4"
- 现在它只能是 4 个数字。编辑:完全修改的 MapRoute 示例:jsfiddle.net/HJRgT【参考方案2】:
你可以把 firstItem 改成 id 就可以了
您可以更改 global.asax 上的路由(我不建议这样做)
而且,不敢相信没有人提到这一点,你可以打电话:
http://localhost:2316/Inventory/ViewStockNext?firstItem=11
在@Url.Action 中是:
@Url.Action("ViewStockNext", "Inventory", new firstItem=11);
根据你所做的类型,最后一个会更合适。 此外,您应该考虑不执行 ViewStockNext 操作,而是执行带有索引的 ViewStock 操作。 (我的 2cents)
【讨论】:
【参考方案3】:要改写Jarret Meyer's answer,您需要将参数名称更改为“id”或添加这样的路由:
routes.MapRoute(
"ViewStockNext", // Route name
"Inventory/ViewStockNext/firstItem", // URL with parameters
new controller = "Inventory", action = "ViewStockNext" // Parameter defaults
);
原因是默认路由只查找不带参数的动作或名为“id”的参数。
编辑:嘿,没关系 Jarret 在发布后添加了路线示例。
【讨论】:
【参考方案4】:或使用路由属性:
public class InventoryController : Controller
[Route("whatever/firstItem")]
public ActionResult ViewStockNext(int firstItem)
int yourNewVariable = firstItem;
// ...
【讨论】:
此属性可能不适用于旧 MVC 版本。 另外,为了使这个工作你需要确保你已经在应用程序的RegisterRoutes(RouteCollection)
方法中调用了routes.MapMvcAttributeRoutes();
(通常在 App_Start\RouteConfig.cs 中搭建)。默认情况下它可能不在那里。【参考方案5】:
Headspring 创建了一个不错的库,允许您在动作属性中为参数添加别名。这看起来像这样:
[ParameterAlias("firstItem", "id", Order = 3)]
public ActionResult ViewStockNext(int firstItem)
// Do some stuff
有了这个,您不必为了处理不同的参数名称而更改路由。该库还支持多次应用它,因此您可以映射多个参数拼写(在不破坏公共接口的情况下进行重构时很方便)。
您可以从Nuget 获取它并阅读 Jeffrey Palermo 的文章here
【讨论】:
【参考方案6】:public ActionResult ViewNextItem(int? id)
使id
整数成为可为空的类型,无需字符串int 转换。
【讨论】:
【参考方案7】:使用 ASP.NET Core Tag Helper 功能:
<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>
【讨论】:
讽刺的是,最短的答案是最好的(这个)。【参考方案8】:还有另一种方法可以实现(在 Stephen Walther 的Pager example 中有更详细的描述
本质上,您在视图中创建了一个链接:
html.ActionLink("Next page", "Index", routeData)
在 routeData 中,您可以指定名称/值对(例如,routeData["page"] = 5),并在控制器索引函数中相应的参数接收值。也就是说,
public ViewResult Index(int? page)
将 page 作为 5 传递。我不得不承认,字符串(“page”)自动成为变量是很不寻常的——但这也是 MVC 在其他语言中的工作方式......
【讨论】:
【参考方案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】:或者,您可以尝试将参数类型更改为字符串,然后在方法中将字符串转换为整数。我是 MVC 的新手,但我相信您的参数列表中需要可为空的对象,否则控制器将如何指示未提供此类参数?所以……
public ActionResult ViewNextItem(string id)...
【讨论】:
以上是关于ASP.NET MVC - 将参数传递给控制器的主要内容,如果未能解决你的问题,请参考以下文章
模型在使用 C# 将 POST 方法作为参数传递给 ASP.NET MVC 中同一控制器的 GET 方法时获取 NULL
如何将多个参数传递给 ASP.NET Core 中的 get 方法
ASP.Net MVC:使用 RedirectToAction() 将字符串参数传递给操作