【问题标题】:What is wrong with my MVC4 Routes, Parameters, constructors?我的 MVC4 路由、参数、构造函数有什么问题?
【发布时间】:2012-10-07 20:31:47
【问题描述】:

我正在编写的一个小应用程序有问题。现在要么我的错误出现在我的控制器类中,要么出现在 Routes 中。见下图。

控制器类。

这是我的默认路线。

这是我运行时遇到的错误。 图片不是很清楚,但上面写着:

参数字典包含“GlobalUnited.WebUI.Controllers”中方法“System.Web.Mvc.ActionResult Detail(Int32)”的不可空类型“System.Int32”的参数“playerId”的空条目.PlayerController'。可选参数必须是引用类型、可空类型或声明为可选参数。 参数名称:参数

我阅读了这里的一些帖子,特别是: Similar Link

当 Daniel Renshaw 说:

首先,我建议您使用 MVC 的参数自动处理,而不是自己将它们从请求中拉出。您的控制器操作有一个似乎被忽略的 id 参数 - 使用它并添加其他类似的参数来获取输入参数。

无论如何,在阅读了那篇文章后,我将 RouteConfig 文件更改为:

我仍然收到此错误。它说:

名为“DefaultApi”的路由已在路由集合中。路由名称必须是唯一的。 参数名称:名称

我什至尝试将我的 Detail 操作参数更改为:注意 int 吗?宣言

更改后出现此错误:

我可以做些什么来解决这个问题,不那么复杂吗? 我们将不胜感激所有帮助,谢谢。

【问题讨论】:

  • +1 用于使用深色主题。 :)
  • 请将代码发布为代码,而不是图像。
  • 感谢 Henk Holterman,我会确保下次这样做
  • 你使用的网址是什么?
  • @MystereMan http://localhost:5169/Player/Detail?PlayerId=1

标签: c# visual-studio routes asp.net-mvc-4 visual-studio-2012


【解决方案1】:

您的参数名称 playerID 导致了这里的问题。 ASP.NET MVC 只能使用默认路由为您提供名为 id 的参数。在您的情况下,它无法将请求映射到您的操作,因为 playerID 不可为空或可选。将参数名称更改为 id 即可解决问题。

public ActionResult Detail(int id)

您在路由注册时遇到第二个错误,因为您已经有一个名为“DefaultApi”的路由。如果更改参数名称(也已在其他地方注册),则不需要此路由。

第三个错误是尝试使用空值进行查询。 ASP.NET MVC 无法将 URL 中的值映射到您的参数,并且您获得默认值 null。由于没有一行具有空值,因此会得到一个空序列,因此 Single() 方法会引发异常。

【讨论】:

  • 我按照你的建议做了,我仍然得到和以前一样的可空错误。而且我还删除了 RouteConfig 中的 DefaultApi。但是如果我问一下,既然 yoy 说这条路线在其他地方注册,你知道它在哪里注册吗?
  • @KomengeMwandila 您如何生成链接?哪个 URL 会导致您出现错误?该路由应在默认 ASP.NET MVC 4 项目的 RouteConfig 类中注册。
  • Haciogullari 这是我要访问的网址:localhost:5169/Player/Detail
  • App_Start\WebApiConfig.cs中注册了DefaultApi路由
  • @KomengeMwandila 那么问题就在这里。您没有为 id 参数提供值。该操作将响应 localhost:5169/Player/Detail/5 之类的 URL。由于您在操作方法中使用 Single(),我认为使用这样的 URL 是不合法的。
【解决方案2】:

由于您的参数称为playerId,您必须将其作为路由值传递给Detail 操作方法,然后检查它是否为空。这将解决您在问题中显示的最后一个错误:序列不包含元素

在动作方法中这样做:

public ActionResult Detail(int? playerId)
{
   if(playerId.HasValue)
   {
       var model = _dataSource.Players.Single(p => p.PlayerId == playerId);

       return View(model);
   }

   // Handle the other possibility where playerId is NULL
}

要让 ASP.NET MVC 知道如何进行正确的参数绑定,您必须以这种方式调用上述操作方法,例如:

@Html.ActionLink("Player Details", "Detail", new { playerId = 1 }); 

【讨论】:

  • playerID 将始终为 null,因为 ASP.NET MVC 对名为 playerID 的参数一无所知。
  • 这是我在索引文件中的内容,其中包含指向详细文件的链接:' @Html.ActionLink(player.Name, "Detail", "Player", new {player.PlayerId},空)'
  • 由于您在操作方法中使用id 作为参数名称而不是playerId,因此您必须使用:@Html.ActionLink(player.Name, "Detail", "Player", new { id = player.PlayerId }, null)。这将使整个事情按预期工作。 :)
  • @LenielMacaferi - 这不是真的,使用他的方法它将创建一个名为 playerId 的查询字符串,然后将值绑定到参数。但是,它不会使用友好的 url 并包含查询字符串。
  • @MystereMan:一个带有id 路由参数的动作链接,就像他在他的动作方法中所拥有的那样......这不正确吗?
【解决方案3】:

除了重复路由错误之外,您的错误与 DefaultApi 路由无关。您会得到一个重复的路由,因为该路由是在 App_Start\WebApiConfig.cs 中配置的

您的第一个问题是您告诉 MVC 您有一个名为 playerId 的强制路由参数,但您没有在您使用的 URL 中提供此路由参数。为了使其工作,您需要更改路线以将 id 更改为 playerId,或将 playerId 查询字符串参数添加到您的 url。如果你改变路线,你需要一个像http://my.site/Player/Detail/1(如果你改变路线)或http://my.site/Player/Detail?playerId=1这样的网址。

另一个选项是将参数更改为public ActionResult Detail(int id),然后将使用现有的默认路由,该路由采用一个名为 id 的参数,并从以/1 结尾的友好 url 中提取它。

您也可以创建Detail(int? id) 方法,但是您需要在您的 linq 查询周围放置一个空保护(因为如果您没有在 URL 上传递 ID,它就无法查找空记录)所以你必须添加这个:

if (id.HasValue) {
    // execute linq query
}

或者,您可以更改查询以返回 SingleOrDefault() 而不是 Single()

【讨论】:

  • 感谢您的输入,这几乎是下面给出的 2 个答案的摘要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多