多个URL相同的动作方法

时间:2018-03-05 13:29:40

标签: asp.net asp.net-mvc routing

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

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方法。所以我希望在输入以下网址时,Test()方法将执行:

  • AController /测试
  • BController /测试

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

3 个答案:

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

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

答案 1 :(得分: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() 
    {
    }
}

答案 2 :(得分:0)

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

[WebMethod]

    public void GetEmployeeById(int Id)  
    {
        Employee employee = new Employee();

        string cs = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
        using (SqlConnection con = new SqlConnection(cs))
        {
            SqlCommand cmd = new SqlCommand("spGetEmployeeById", con);
            cmd.CommandType = CommandType.StoredProcedure;

            SqlParameter parameter = new SqlParameter();
            parameter.ParameterName = "@Id";
            parameter.Value = Id;

            cmd.Parameters.Add(parameter);
            con.Open();
            SqlDataReader rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
                employee.Id = Convert.ToInt32(rdr["Id"]);
                employee.FirstName = rdr["FirstName"].ToString();
                employee.LastName = rdr["LastName"].ToString();
                employee.Gender = rdr["Gender"].ToString();
                employee.JobTitle = rdr["JobTitle"].ToString();
                employee.Salary = Convert.ToInt32(rdr["Salary"]);
                employee.HireDate = Convert.ToDateTime(rdr["HireDate"]);
            }
        }

        JavaScriptSerializer js = new JavaScriptSerializer();
        Context.Response.Write(js.Serialize(employee));
    }

这可以在一个地方实现实际功能。我们在许多项目中使用此方法,没有任何问题。