为啥 T4MVC 尝试从 Html.ActionLink 运行控制器动作?

Posted

技术标签:

【中文标题】为啥 T4MVC 尝试从 Html.ActionLink 运行控制器动作?【英文标题】:Why does T4MVC try to run controller actions from Html.ActionLink?为什么 T4MVC 尝试从 Html.ActionLink 运行控制器动作? 【发布时间】:2011-03-22 03:35:51 【问题描述】:

在我的控制器中,我传入了一个 IUnitOfWork 对象(从 IoC 生成),然后在控制器操作中用于数据库功能(IUnitOfWork 被传递到我的服务层)。

在我的一个观点中,我想给出一个指向/Company/View/<id>的链接,所以我调用如下:

<li>@html.ActionLink(company.Name, MVC.Company.View(company.Id))</li>

这不是从Company 控制器调用的,而是从不同控制器中的视图调用的。问题似乎是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 以这种方式运行有什么原因吗?


编辑: 以下是 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; 

【问题讨论】:

您的实际操作不应该被调用。您能否提供更多关于您的公司控制器的详细信息以及操作方法的详细信息?我不需要 impl 细节,只需要声明。 我已经添加了在这个中使用的控制器、构造函数和动作声明。如果你的意思是别的让我知道,我会更新它。谢谢! 似乎您缺少操作中的方法名称。另外,您能否包括 MyCustomBaseController 及其构造函数?我的目标是能够重现您在小型应用上看到的内容。 抱歉我贴错了。我用我的代码库中的真实代码更新了它。 @KallDrexx ActionLink 在其中携带当前控制器;请改用RouteLink。如果可行,请告诉我,我会写下来作为答案。 【参考方案1】:

奇怪,我无法用上面的代码重现这个问题。应该发生的事情是调用 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 下)。

【讨论】:

这很烦人。显然它从未重新生成 CompanyController T4,因为View() 不在其中,但我的所有其他操作都在其中。希望它更自动,但明确地重新运行 T4 似乎已经修复了它,而且我没有更多的崩溃。标记为感谢你帮助我摆脱我的白痴的答案:) 您可能想查看chirpy.codeplex.com 以了解自动运行 T4MVC 的方法。 太棒了。我以前使用 chirpy 进行 JS 合并,但不知道它可以处理 t4。谢谢!

以上是关于为啥 T4MVC 尝试从 Html.ActionLink 运行控制器动作?的主要内容,如果未能解决你的问题,请参考以下文章

T4MVC,过时了吗?还好?如果不是还有啥用?

T4MVC 无法生成带有 ErrorGeneratingOutput 的类

当前上下文中不存在ViewBag

正则表达式替换:匹配中的多个替换

如何动态覆盖 Html.ActionLink 生成的 URL?

为啥我的 Flask 尝试从不同的目录导入?