3

我想同时访问 /Blog 和 /Blog/1,其中“1”是博客的 ID。这是我的代码:

    '
    ' GET: /Blog/

    Function Index() As ViewResult
        Return (View(db.Blogs.ToList()))
    End Function

    '
    ' GET: /Blog/(Integer)

    Function Index(id As Integer) As ViewResult
        Dim blog As Blog = db.Blogs.Find(id)
        Return View("Details", "_MyLayout", blog)
    End Function

它给出了错误:

“/”应用程序中的服务器错误。

当前对控制器类型“BlogController”的操作“Index”请求在以下操作方法之间不明确:GemcoBlog.GemcoBlog.BlogController System.Web.Mvc.ViewResult Index(Int32) 类型上的 System.Web.Mvc.ViewResult Index()在 GemcoBlog.GemcoBlog.BlogController 类型上

说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Reflection.AmbiguousMatchException:当前对控制器类型“BlogController”的操作“Index”的请求在以下操作方法之间不明确:System.Web.Mvc.ViewResult Index() 类型 GemcoBlog.GemcoBlog.BlogController System。类型 GemcoBlog.GemcoBlog.BlogController 上的 Web.Mvc.ViewResult Index(Int32)

源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

如何重载 Index() 方法?

编辑:

我也试图像这样组合它们:

    '
    ' GET: /Blog/

    Function Index(id As Integer) As ViewResult
        If (id) Then
            Dim blog As Blog = db.Blogs.Find(id)
            'Return View(blog)
            Return View("Details", "_MyLayout", blog)
        Else
            Return (View(db.Blogs.ToList()))
        End If
        'Return View(db.Blogs.Where(Function(x) x.Name = "Test").ToList())
    End Function

但是,我得到的错误是:

“/”应用程序中的服务器错误。

参数字典包含“Blog.Blog.BlogController”中方法“System.Web.Mvc.ViewResult Index(Int32)”的不可空类型“System.Int32”的参数“id”的空条目。可选参数必须是引用类型、可空类型或声明为可选参数。参数名称:参数

说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.ArgumentException:参数字典包含“Blog.Blog”中方法“System.Web.Mvc.ViewResult Index(Int32)”的不可空类型“System.Int32”的参数“id”的空条目。博客控制器'。可选参数必须是引用类型、可空类型或声明为可选参数。参数名称:参数

源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

4

4 回答 4

2

您不能在同一个控制器上使用相同的 HTTP 动词访问 2 个操作。因此,要么更改操作名称,要么您必须使用不同的 HTTP 动词来消除歧义。例如:

<HttpPost>
Function Index(id As Integer) As ViewResult
    Dim blog As Blog = db.Blogs.Find(id)
    Return View("Details", "_MyLayout", blog)
End Function

但由于其他操作似乎也在获取数据,我猜你不想让它只能通过 POST 访问。所以在这种情况下只需重命名它。坚持标准 RESTful 约定,您可以使用它Index来返回资源列表并Show返回特定资源:

Function Index() As ViewResult
    Return (View(db.Blogs.ToList()))
End Function

'
' GET: /Blog/(Integer)

Function Show(id As Integer) As ViewResult
    Dim blog As Blog = db.Blogs.Find(id)
    Return View("Details", "_MyLayout", blog)
End Function
于 2012-07-26T16:20:17.750 回答
2

有几种方法可以做到这一点。最简单的方法是将第一个方法重命名为“ShowBlog”或您想要的任何名称,然后在 global.asax 中设置一个路由,该路由无需参数即可路由到 /Blog 路由。

例如(在 c# 中):

routes.MapRoute("Blog", "Blog", new { controller = "Blog", action = "ShowBlog" });

确保 MapRoute 位于默认路由之前。

要使您的第二种方法起作用,您需要使 id 可以为空,然后在您的方法中检查 null。

于 2012-07-26T16:59:39.707 回答
1

由于它不可为空,因此它会自动假定您默认提供了一个 id。将 Id 设为 Nullable Integer,它将适用于两个 URL。

函数索引(id 作为 Nullabe(整数))作为 ViewResult

于 2012-07-26T16:58:52.753 回答
0

对 Erik 的帖子进行小修改以使其正常工作(我正在使用 MVC4)

routes.MapRoute("Blog", "Blog/{id}", new { controller = "Blog", action = "ShowBlog" });
于 2014-08-20T02:14:01.323 回答