为什么 T4MVC 尝试从 Html.ActionLink 运行控制器操作?

发布于 2024-10-24 14:16:28 字数 1634 浏览 0 评论 0原文

在我的控制器中,我传入一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北恋 2024-10-31 14:16:28

奇怪的是,我无法用上面的代码重现这个问题。应该发生的情况是,调用 MVC.Company.View(company.Id) 最终会调用您的操作方法的重写,而不会真正调用您真正的操作方法。

为了实现这项工作,生成的代码应该如下所示(仅保留相关内容):

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;
    }
}

您可以查看生成的代码,看看它是否有任何不同吗?首先在“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):

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文