我正在写一个小应用程序的问题。现在要么我的错误在我的控制器类中,要么在路由中。见下图。
控制器类。
这是我的默认路线。
这是我跑步时得到的错误。 图像不是很清楚,但它说:
参数字典包含参数' playerId'的空条目。非可空类型的System.Int32' for method' System.Web.Mvc.ActionResult Detail(Int32)'在' GlobalUnited.WebUI.Controllers.PlayerController'。可选参数必须是引用类型,可空类型,或者声明为可选参数。 参数名称:参数
我在这里阅读了一些帖子,特别是: Similar Link
当Daniel Renshaw说道时,他究竟是什么意思:
首先,我建议您使用MVC自动处理参数,而不是自己从请求中删除它们。你的控制器动作有一个id参数似乎被忽略了 - 使用它并添加其他类似参数来获取输入参数。
无论如何,在阅读该帖子后,我将RouteConfig文件更改为:
仍然有这个错误。它说:
名为' DefaultApi'的路线已经在路线集合中。路线名称必须是唯一的。 参数名称:名称
我甚至尝试将我的Detail动作参数更改为:注意int?宣言
更改后我收到了这个错误:
我有什么办法可以解决这个问题吗? 感谢所有帮助。
答案 0 :(得分:6)
您的参数名称playerID会导致此处出现问题。 ASP.NET MVC只能使用默认路由为您提供名为id的参数。在您的情况下,它无法将请求映射到您的操作,因为playerID不可为空或可选。将参数名称更改为id将解决问题。
public ActionResult Detail(int id)
路由注册会出现第二个错误,因为您已经有一条名为“DefaultApi”的路由。如果更改参数名称(也在其他地方注册),则不需要此路径。
第三个错误是尝试使用空值进行查询。 ASP.NET MVC无法将URL中的值映射到您的参数,您将获得默认值null。由于没有一个空值的行,你得到一个空序列,然后Single()方法抛出异常。
答案 1 :(得分:1)
由于您的参数名为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 });
答案 2 :(得分:1)
除了重复的路由错误之外,您的错误与DefaultApi路由无关。您获得重复的路由,因为该路由在App_Start \ WebApiConfig.cs
中配置你的第一个问题是你告诉MVC你有一个名为playerId的必需Route参数,但是你没有在你正在使用的URL中提供这个route参数。为了实现这一点,您需要更改路由以将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()
。