多个URL相同的动作方法

问题描述 投票:-1回答:3

我需要在不同的控制器之间共享动作方法。以下面的2个控制器为例:

public class AController : Controller
{
       public ActionResult Index()
       {
           //print AController - Index
       }

       public ActionResult Test()
       {
           //print test
       }
}

public class BController : Controller
{
     public ActionResult Index()
     {
         //print BController - Index
     }
}

两个控制器都有一个不同的Index方法。但是,可以从两个控制器调用Test方法。所以我希望在输入以下URL时,Test()方法将执行:

  • AController /测试
  • BController /测试

我很感激有关如何实现这一目标的任何建议。

asp.net asp.net-mvc routing
3个回答
1
投票

假设Test()动作的实现对于两个控制器都是相同的,将它重构为一个公共服务:

public interface ITestService {
    string Test();
}

public TestService: ITestService {
    public string Test() {
        // common implementation
        return "The test result";
    }
}

然后设置Dependency Injection以获得此服务。

然后,您的控制器可以使用公共服务。

public class AController : Controller {

    private readonly ITestService _testService;

    public AController(ITestService testservice) {
        _testService = testservice;
    }

    public ActionResult Test() {
        var vm = new TestViewModel();
        vm.TestResult = _testService.Test();
        return View("Test", vm);
    }
}

public class BController : Controller {

    private readonly ITestService _testService;

    public BController(ITestService testservice) {
        _testService = testservice;
    }

    public ActionResult Test() {
        var vm = new TestViewModel();
        vm.TestResult = _testService.Test();
        return View("Test", vm);
    }
}

因为View Test.cshtml由两个控制器呈现,所以它应该放在Views\Shared\文件夹中。


0
投票

您可以按照此处所述定义自己的路线:https://docs.microsoft.com/aspnet/core/mvc/controllers/routing

因此,您可以根据需要定义任意数量的路径,以指向“AController”中的“Test”方法,如下所示:

routes.MapRoute("Atest", "AController/Test",
        defaults: new { controller = "AController", action = "Test" });
routes.MapRoute("Btest", "BController/Test",
        defaults: new { controller = "AController", action = "Test" });

但您必须在“默认”路线之前定义它们,否则输入的URL将与默认路线条件匹配,因此它将进入该路线。

也可以直接在方法的顶部定义路线。

public class AController : Controller
{
    [Route("/Some/Route")]
    public ActionResult Test() 
    {
    }
}

0
投票

我想提出一个替代解决方案。创建一个由其他两个继承的基本控制器类。无论你拥有什么,都会有一部分孩子。

public class BaseController : Controller
{
    public ActionResult Index()
    {
        //print AController - Index
    }

    // Add more methods to be shared between the other controllers
}

public class AController : BaseController 
{
    // Has Index method already from parent

    // Unique method for A
    public ActionResult Test()
    {
        //print test 1
    }
}

public class BController : BaseController
{
    // Has Index method already from parent

    // Unique method for B
    public ActionResult Test()
    {
        //print test 2
    }
}

这在单个位置实现了实际功能。我们将此方法用于许多项目而没有任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.