MVC控制器中的重载索引()方法

时间:2012-07-26 16:17:20

标签: asp.net-mvc vb.net asp.net-mvc-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'在以下操作方法之间不明确:   System.Web.Mvc.ViewResult索引()类型   GemcoBlog.GemcoBlog.BlogController System.Web.Mvc.ViewResult   GemcoBlog.GemcoBlog.BlogController类型的索引(Int32)

     

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.Reflection.AmbiguousMatchException:The   控制器类型'BlogController'上的当前动作请求'索引'   以下操作方法之间不明确:   System.Web.Mvc.ViewResult索引()类型   GemcoBlog.GemcoBlog.BlogController System.Web.Mvc.ViewResult   GemcoBlog.GemcoBlog.BlogController类型的索引(Int32)

     

来源错误:

     

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

如何重载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

然而,我得到的错误是:

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

  

参数字典包含参数'id'的空条目   方法'System.Web.Mvc.ViewResult'的非可空类型'System.Int32'   'Blog.Blog.BlogController'中的索引(Int32)'。可选的   参数必须是引用类型,可空类型或声明为   一个可选参数。参数名称:参数

     

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.ArgumentException:参数字典   包含非可空类型的参数“id”的空条目   'System.Int32'用于方法'System.Web.Mvc.ViewResult Index(Int32)'in   'Blog.Blog.BlogController'。可选参数必须是a   引用类型,可空类型,或声明为可选   参数。参数名称:参数

     

来源错误:

     

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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

例如(在c#中):

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

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

要使第二个方法有效,您需要使id可为空,然后在方法中检查null。

答案 2 :(得分:1)

由于它不可为空,因此它会自动假定您默认提供id。使Id成为可以为空的整数,它将适用于两个URL。

函数索引(id为Nullabe(Of Integer))作为ViewResult

答案 3 :(得分:0)

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

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