[英]Routing from one view to another controller's action method and passing a parameter to that controller's constructor
I'm creating my first C# MVC site and quite early on I've hit a roadblock where I'm not sure if I'm going about things entirely the wrong way and I can't find an example similar to my own online but it seems like what I'm trying to do should be straightforward. 我正在创建我的第一个C#MVC网站,但很早以前,我遇到了一个障碍,在那我不确定是否要以完全错误的方式进行事情,并且找不到与我自己的在线网站类似的示例,但是看来我要做的事情应该很简单。
Basically, I have my initial controller (called ClientController) that sets up a list of clients and then displays them in my list view: 基本上,我有一个初始控制器(称为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());
}
}
Then in my view I have an action link where I want to route to my UserController, passing it the client name, so that it can build the list of users for that particular client. 然后在我看来,我有一个操作链接,该路由要路由到我的UserController,并向其传递客户端名称,以便它可以为该特定客户端构建用户列表。
@Html.ActionLink("View Admin Users","Index","User",new {clientName = item.ClientName},null)
This works with the following code: 这适用于以下代码:
public class UserController : Controller
{
private IUserManagerRepository _userManagerRepository;
//
// GET: /User/
public ActionResult Index(string clientName)
{
_userManagerRepository = new EntityUserManagerRepository(clientName);
return View(_userManagerRepository.GetAllUsers());
}
}
And my list of users is displayed correctly in my view. 并且我的用户列表在我的视图中正确显示。
However, when I then add in my details action method it doesn't work because the _userManagerRepository
isn't instantiated: 但是,当我随后在我的details操作方法中添加该方法时,由于
_userManagerRepository
未实例化,因此它不起作用:
//
// GET: /User/Details/5
public ActionResult Details(int contactId)
{
return View(_userManagerRepository.GetUser(contactId));
}
I would have to I guess pass in the clientname each time and re-instantiate my _userManagerRepository. 我必须每次都传入客户名,然后重新实例化_userManagerRepository。 That doesn't feel like a very good way though.
不过,这并不是一个很好的方法。
Ideally I'd like to create my _userManagerRepository
in the constructor of my UserController. 理想情况下,我想在UserController的构造函数中创建
_userManagerRepository
。 I've been looking into how I would do this so I'd have something like: 我一直在研究如何做到这一点,所以我会得到一些类似的信息:
public class UserController : Controller
{
private IUserManagerRepository _userManagerRepository;
public UserController(string clientname)
: this(new EntityUserManagerRepository(clientname))
{
}
public UserController(IUserManagerRepository repository)
{
_userManagerRepository = repository;
}
I've researched that I can create my own controller factory so that I can have a parameter in my userController constructor however I still don't understand how I would pass my clientname parameter form a view to my UserController. 我研究过可以创建自己的控制器工厂,以便可以在userController构造函数中有一个参数,但是我仍然不知道如何将客户名参数从视图传递给UserController。
If you want to instantiate Repository class in controller's constructor,you can use NInject , it's really nice approach to do it. 如果要在控制器的构造函数中实例化Repository类,则可以使用NInject ,这是一种非常好的方法。
1-Install Ninject from Nuget 2-Create Repository Abstract for example ICustomerRepository 1-从Nuget安装Ninject 2-创建存储库摘要,例如ICustomerRepository
public abstract ICustomerRepository
{
string GetCustomerName();
}
3-Create Repository for example CustomerRepository 3-创建存储库,例如CustomerRepository
public class CustomerRepository:ICustomerRepository
{
string GetCustomerName()
{
return ("John");
}
}
4-create CustomerControllerFactory Class 4创建CustomerControllerFactory类
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().To(typeof(CustomerRepository)); ninjectKernel.Bind()。To(typeof(CustomerRepository));
I bind ICustomerRepository to CustomerRepository in upper code 我用较高代码将ICustomerRepository绑定到CustomerRepository
5- Add below code to Application_Start 5-将以下代码添加到Application_Start
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());
6-Create New Controller 6-创建新控制器
public class CustomerController:Controller
{
public CustomerController(ICustomerRepository customerRepository)
{
//customerRepository instantiate to CustomerRepostory Class automatically
}
}
it's Dependency Injection that i think useful for you 我认为对您有用的依赖注入
Regards 问候
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.