为什么 T4MVC 尝试从 Html.ActionLink 运行控制器操作?
在我的控制器中,我传入一个 IUnitOfWork
对象(从 IoC 生成),然后在控制器操作中使用该对象来实现数据库功能(IUnitOfWork
被传递到我的服务层) 。
在我的一个视图中,我想提供一个指向 /Company/View/
的链接,因此我调用以下内容:
<li>@Html.ActionLink(company.Name, MVC.Company.View(company.Id))</li>
这不是从 Company
调用的code> 控制器,但是来自不同控制器中的视图。问题似乎是 MVC.Company.View(company.Id)
似乎实际上是在调用 CompanyController.View(id)
方法本身。这很糟糕,有两个原因。
1) 由于 CompanyController
的非无参数构造函数永远不会被调用,因此不存在 UnitOfWork
,因此当 View(int id)
操作时被调用时,该操作的数据库调用会失败并出现 NullReferenceException。
2) 即使 IUnitOfWork
存在,我的视图不应该触发数据库调用,以便生成链接。据我所知, Html.ActionLink(company.Name, "View", new { id = company.Id })
不会触发任何数据库调用(因为未调用操作方法)我担心 tml.ActionLink(company.Name, MVC.Company.View(company.Id)) 也不应该触发任何数据库调用。过多的数据库调用绝对没有任何好处。
创建 T4MVC 是否有任何理由以这种方式运行?
Edit: Here are the declarations for the CompanyController
public partial class CompanyController : MyCustomBaseController
{
public CompanyController(IUnitOfWork unitOfWork)
{
}
public virtual ActionResult Add(int jobSearchId)
{
}
public virtual ActionResult Edit(int id)
{
}
[HttpPost]
public virtual ActionResult Edit(Company company, int jobSearchId)
{
}
public virtual ActionResult View(int id)
{
}
}
public class MyCustomBaseController: Controller
{
public MyCustomBaseController()
{
}
public int CurrentUserId { get; set; }
}
In my controllers I pass in a IUnitOfWork
object (which is generated from IoC) which is then used in controller actions for database functionality (the IUnitOfWork
is passed to my service layer).
In one of my views, I want to give a link to the /Company/View/<id>
, so I call the following:
<li>@Html.ActionLink(company.Name, MVC.Company.View(company.Id))</li>
This is being called not from the Company
controller, but from a view in a different controller. The problem seems to be that the MVC.Company.View(company.Id)
seems to actually be invoking the CompanyController.View(id)
method itself. This is bad for 2 reasons.
1) Since the CompanyController
's non-parameterless constructor is never called, no UnitOfWork
exists, and thus when the View(int id)
action is called, the action's database calls fail with a NullReferenceException
.
2) Even if IUnitOfWork
exists, my view should not be triggering database calls just so my links are generated. Html.ActionLink(company.Name, "View", new { id = company.Id })
doesn't trigger any database calls (as the action method isn't invoked) so as far as I'm concerned tml.ActionLink(company.Name, MVC.Company.View(company.Id))
shouldn't be triggering any DB calls either. It's excessive database calls for absolutely no gain.
Is there any reason T4MVC was created to function this way?
Edit: Here are the declarations for the CompanyController
public partial class CompanyController : MyCustomBaseController
{
public CompanyController(IUnitOfWork unitOfWork)
{
}
public virtual ActionResult Add(int jobSearchId)
{
}
public virtual ActionResult Edit(int id)
{
}
[HttpPost]
public virtual ActionResult Edit(Company company, int jobSearchId)
{
}
public virtual ActionResult View(int id)
{
}
}
public class MyCustomBaseController: Controller
{
public MyCustomBaseController()
{
}
public int CurrentUserId { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
奇怪的是,我无法用上面的代码重现这个问题。应该发生的情况是,调用 MVC.Company.View(company.Id) 最终会调用您的操作方法的重写,而不会真正调用您真正的操作方法。
为了实现这项工作,生成的代码应该如下所示(仅保留相关内容):
您可以查看生成的代码,看看它是否有任何不同吗?首先在“MVC”上执行“转到定义”,这将打开 T4MVC.cs(在 T4MVC.tt 下)。
Strange, I'm not able to repro this issue with the code above. What should be happening is that calling MVC.Company.View(company.Id) ends up calling an override of your action method, and never actually call your real action method.
To make this work, the generated code should look like this (only keeping relevant things):
Can you look at the generated code you get to see if it's any different? Start by doing a 'Go To Definition' on 'MVC', which will open up T4MVC.cs (under T4MVC.tt).