开发者

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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜