Why does T4MVC try to run controller actions from Html.ActionLink?
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; }
}
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):
public static class MVC {
public static Mvc3Application.Controllers.CompanyController Company = new Mvc3Application.Controllers.T4MVC_CompanyController();
}
public class T4MVC_CompanyController: Mvc3Application.Controllers.CompanyController {
public T4MVC_CompanyController() : base(Dummy.Instance) { }
public override System.Web.Mvc.ActionResult View(int id) {
var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.View);
callInfo.RouteValueDictionary.Add("id", id);
return callInfo;
}
}
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).
精彩评论