同一个控制器中的AmbiguousActionException

时间:2017-02-15 09:41:14

标签: c# asp.net-core asp.net-mvc-areas

我一直在尝试使用Asp.NET Core,特别是Area。现在我遇到了一个问题,如果我向控制器添加了多个视图,我会遇到异常。

这是我的例外:

  

处理请求时发生未处理的异常。

     

AmbiguousActionException:匹配多个动作。以下操作匹配路由数据并满足所有约束:

     

Forum.Areas.Admin.Controllers.AdminController.Index(论坛)   Forum.Areas.Admin.Controllers.AdminController.Testing(论坛)

这是我注册路线的方式:

  app.UseMvc(routes =>
  {
    routes.MapRoute("adminRoute", "Admin/{controller}/{action}/{id?}");

    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });

我的控制器:

namespace Forum.Areas.Admin.Controllers
{
  [Area("Admin")]
  [Route("admin")]
  public class AdminController : Controller
  {

    public IActionResult Index()
    {
      return View();
    }

    public IActionResult Testing()
    {
      return Content("Testing area!");
    }
  }
}

我的项目结构:

Project structure

其他类似的问题似乎对不同的控制器有不明确的行为,但就我而言,它有两个不同的动作名称?我是否错误地注册了路线?

编辑:请不要评论我的" 2个标签位置"缩进 - 它是工作中的风格指南,我没有发言权:(

提前致谢!

1 个答案:

答案 0 :(得分:4)

首先,您在Route中不需要AdminController属性,因为您在app.UseMvc()中注册了路线 - 删除[Route("admin")]

另外,您应该在app.UseMvc()中更改路线。

这条路线:

routes.MapRoute("adminRoute", "Admin/{controller}/{action}/{id?}");

应更改为:

routes.MapRoute("adminRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

您需要在路线中设置区域,并为controlleraction设置默认值(没有必要设置默认值,但稍后会在答案中说明。)

因此,要调用Index()操作,您应该输入url

http://localhost:yourPortNumber/Admin

在此向Admin区域发出请求,并使用默认值(Admin作为默认控制器,Index作为默认操作)。您可以更改此路线的默认值。

注意:如果您没有在路线中设置默认值,那么之前的链接就无法使用,您应该将url写满行动 - 请参阅下文。

致电Testing()行动url应为:

http://localhost:yourPortNumber/Admin/Admin/Testing

在此处指定区域名称(Admin),控制器名称(Admin)和操作名称(Testing

以同样的方式,你可以调用Index()动作和其他动作(如果你需要更多):

http://localhost:yourPortNumber/Admin/Admin/Index

http://localhost:yourPortNumber/Admin/Admin/AntoherActionName

因此,您的路线应该通过这种方式配置:

app.UseMvc(routes =>
{
  routes.MapRoute("adminRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

  routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
});

和您的控制人员:

[Area("Admin")]  
public class AdminController : Controller
{     
  public IActionResult Index()
  {
    return View();
  }

  public IActionResult Testing()
  {
    return Content("Testing area!");
  }
}

修改

您还可以在路线配置中设置默认区域:

routes.MapRoute("adminRoute", "{area=Admin}/{controller=Admin}/{action=Index}/{id?}");

现在,当您默认运行应用程序时,将使用route:

http://localhost:your_port_number/Admin/Admin/Index