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() 将字符串参数传递给操作

如何将参数传递给 ASP.NET MVC 中的局部视图?

如何将多个参数传递给 ASP.NET CORE MVC 中的 HttpGet 方法?

如何将参数传递给 jQuery document.ready() 函数(ASP.NET MVC、C#)