【问题标题】:Overriding does not work on virtual method in ASP.net Core MVC覆盖不适用于 ASP.net Core MVC 中的虚拟方法
【发布时间】:2018-07-15 14:55:33
【问题描述】:
namespace ProjectA.Controllers
public partial class CustomerController : Controller
{
 public virtual IActionResult Index()
 {
  ...Some code here
 }

 public virtual IActionResult Login()
 {
  ...Some code here
 }
}


namespace ProjectB.Controllers
public partial class CustomerController : ProjectA.Controllers.CustomerController
{
 public override IActionResult Login()
 {
  ...Some code here
 }
}

当我尝试像上面那样覆盖时,它给了我下面的错误

AmbiguousActionException:匹配多个动作。 以下操作匹配路由数据并满足所有约束: ProjectA.Controllers.CustomerController.Index (ProjectA) ProjectB.Controllers.CustomerController.Index (ProjectB)

虽然 ProjectB 中没有索引操作。当我将 ProjectB 的控制器名称更改为:

namespace ProjectB.Controllers
public partial class CustomCustomerController : ProjectA.Controllers.CustomerController
{
 public override IActionResult Login()
 {
  ...Some code here
 }
}

AmbiguousActionException 消失了,但覆盖仍然不起作用。我没有接到覆盖行动的电话。 是不是 .Net 核心不再支持覆盖,因为它在没有 .net 核心且控制器名称相同的情况下就像魅力一样工作。 请帮忙..

【问题讨论】:

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


    【解决方案1】:

    因为您的两个类名都为“CustomerController”。两者都可能使用默认路由。所以两个控制器的 url 应该和/{controller}/{action}一样。

    因此对于相同的 url,每个控制器将有 2 个可用的操作。这就是为什么你得到 ​​p>

    “AmbiguousActionException”异常。

    当您将子控制器更改为“CustomCustomerController”时,两个控制器的 url 都会更改,因此不会发生这种歧义,因此它起作用了。

    正如你所说,覆盖不起作用。在这种情况下,您必须将 url 用作“/CustomCustomer/login”,然后它将转到 CustomCustomerController 的登录操作。

    编辑 1

    您可以如下更新您的代码,它应该可以正常工作。如下创建您的控制器:

    namespace ProjectA.Controllers {
        public partial class CustomerController : Controller
        {
            public virtual IActionResult Index()
            {
                ...Some code here
            }
    
            public virtual IActionResult Login()
            {
                ...Some code here
            }
        }
    }
    
    namespace ProjectB.Controllers {
        public partial class CustomCustomerController : ProjectA.Controllers.CustomerController
        {
            public override IActionResult Login()
            {
                ...Some code here
            }
        }
    }
    

    并将app.UseMvc(routes => 部分更新为startup.cs,如下所示。在default 路由之前添加customer 路由。

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "customer",
            template: "customer/{action}/{id?}",
            defaults: new { controller = "CustomCustomer", action = "Index" });
    
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
    

    【讨论】:

    • 你好,谢谢你的回答,但我不能像你说的那样使用 url,因为在视图页面中它被写成固定的“客户/登录”,我不想转向自定义视图页面正在使用 C# 代码。正如我在 MVC5 项目中所说的,这在 .Net MVC Core 项目中运行良好。
    • @NopAdvance 你检查过 routeconfig.cs 在两个项目中是否完全相同?
    • 嗨@karan,你有没有在.net core mvc中做过这个?
    • @NopAdvance,是的,我使用过核心。您是否在 startup.cs app.UseMvc(routes => 中签入了您的核心项目,其 routes.MapRoute( 与旧项目的 RouteConfig.cs 相同?
    • 嗨..谢谢。我会尽快检查并更新
    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    相关资源
    最近更新 更多