从一个视图路由到另一个控制器的操作方法并将参数传递给该控制器的构造函数

时间:2014-06-22 14:41:43

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

我正在创建我的第一个C#MVC网站,很早就开始我遇到了障碍,我不确定我是否会以完全错误的方式处理事情,我找不到类似于我的示例在线,但似乎我想做的事情应该是直截了当的。

基本上,我有我的初始控制器(称为ClientController),它设置了一个客户列表,然后在我的列表视图中显示它们:

public class ClientController : Controller
{

    private readonly IClientManagerRepository _clientManagerRepository;

    public ClientController()
        : this(new EntityClientManagerRepository())
    {
    }

    public ClientController(IClientManagerRepository repository)
    {
        _clientManagerRepository = repository;
    }

    //
    // GET: /Client/
    public ViewResult List()
    {

        return View(_clientManagerRepository.GetAllClients());

    }
}

然后在我看来,我有一个动作链接,我想要路由到我的UserController,并传递客户端名称,以便它可以为该特定客户端构建用户列表。

@Html.ActionLink("View Admin Users","Index","User",new {clientName = item.ClientName},null)

这适用于以下代码:

public class UserController : Controller
{     
    private IUserManagerRepository _userManagerRepository;

    //
    // GET: /User/
    public ActionResult Index(string clientName)
    {
        _userManagerRepository = new EntityUserManagerRepository(clientName);
        return View(_userManagerRepository.GetAllUsers());
    }

}

我的视图中正确显示了我的用户列表。

然而,当我添加我的详细信息操作方法时,它不起作用,因为_userManagerRepository未实例化:

//
// GET: /User/Details/5
public ActionResult Details(int contactId)
{
    return View(_userManagerRepository.GetUser(contactId));
}

我不得不每次都传递客户端名称并重新实例化我的_userManagerRepository。但这并不是一种非常好的方式。

理想情况下,我想在UserController的构造函数中创建_userManagerRepository。我一直在研究如何做到这一点所以我有类似的东西:

public class UserController : Controller
{


    private IUserManagerRepository _userManagerRepository;

    public UserController(string clientname)
        : this(new EntityUserManagerRepository(clientname))
    {
    }

    public UserController(IUserManagerRepository repository)
    {
        _userManagerRepository = repository;
    }

我研究过我可以创建自己的控制器工厂,这样我就可以在userController构造函数中有一个参数但是我仍然不明白如何将视图中的clientname参数传递给我的UserController。

1 个答案:

答案 0 :(得分:0)

如果要在控制器的构造函数中实例化Repository类,可以使用NInject, 这是非常好的做法。

1 - 从Nuget安装Ninject 2-Create Repository Abstract,例如ICustomerRepository

public abstract ICustomerRepository
{
   string GetCustomerName();
}

3-Create Repository,例如CustomerRepository

public class CustomerRepository:ICustomerRepository
{
    string GetCustomerName()
    {
       return ("John");
    }

}

4-create CustomerControllerFactory Class

public class CustomControllerFactory : DefaultControllerFactory
    {
        private static IKernel ninjectKernel;
        public CustomControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings(ninjectKernel);
        }

        protected override IController GetControllerInstance
            (System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                return (new Controllers.MessageController());
            }
            else
            {
                return ((IController)ninjectKernel.Get(controllerType));
            }
        }

        public static void AddBindings(IKernel ninjectKernel)
        {
            Common.DependencyInjection.DependencyManager.GetDependencyInjections().ForEach(current =>
            {
                if (current.Abstract != null && current.Implementation != null)
                {
                    ninjectKernel.Bind(current.Abstract).To(current.Implementation);
                }
            });

            ninjectKernel.Bind<ICustomerRepository>().To(typeof(CustomerRepository));
        }
    }

<强> ninjectKernel.Bind()为了(typeof运算(CustomerRepository));

我将ICustomerRepository绑定到上层代码中的CustomerRepository

5-将以下代码添加到Application_Start

ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());

6 - 创建新控制器

public class CustomerController:Controller
{
    public CustomerController(ICustomerRepository customerRepository)
   {
       //customerRepository instantiate to CustomerRepostory Class automatically
   }
}

这是我觉得对你有用的依赖注入

此致