基类中的 ExecuteCore() 未在 MVC 4 beta 中触发

Posted

技术标签:

【中文标题】基类中的 ExecuteCore() 未在 MVC 4 beta 中触发【英文标题】:ExecuteCore() in base class not fired in MVC 4 beta 【发布时间】:2012-03-22 05:47:40 【问题描述】:

我有一个基本控制器类:

而我所有的其他控制器都像这样继承这个 BaseClass

所有这些在 MVC3 中都很好用(今天再次测试,它确实有效)但似乎 BaseController 中的 ExecuteCore 在 MVC 4 beta 中不再被触发。

有什么想法吗?或者引擎盖下有什么巨大的变化?非常感谢。

public class BaseController : Controller

    private string _myData;

    public string MyData
    
        get
        
            return _myData;
        
    

    protected override void ExecuteCore()
    
        _myData = "I am doing something";

        base.ExecuteCore();
    



public class HomeController : BaseController

    public ActionResult Index()
    
        ViewBag.MyData = MyData;
        // Doing something with value in BaseClass

        return View();
    

【问题讨论】:

【参考方案1】:

我能够重现您的问题。似乎ExecuteCore 的用法发生了变化。但我没有找到任何关于它的信息。我猜这与现在Controller 实现IAsyncController 而不是AsyncController 的事实有关。

但是我找到了一种解决方法来获得 MVC4 的旧行为:

将此添加到BaseContoller

protected override bool DisableAsyncSupport

    get  return true; 

来自DisableAsyncSupport 的 MSDN 页面(重点由我添加):

此标志用于向后兼容。 ASP.NET MVC 4. 允许控制器支持异步模式。这意味着ExecuteCore 不会在派生类上被调用。 如果派生类仍需要调用 ExecuteCore,则可以覆盖此标志并将其设置为 true

【讨论】:

感谢您的评论。似乎 MVC 团队真的改变了一些东西。我有另一个可以解决这个问题的解决方法:我覆盖了 BaseClass 中的 OnActionExecuting,而不是 ExecuteCore,它会被正确触发。 此时,MSDN 页面不是空的,并且包含以下注释:“此标志是为了向后兼容。ASP.NET MVC 4. 允许控制器支持异步模式。这意味着 ExecuteCore 不在派生类上调用。如果派生类仍然需要调用 ExecuteCore,则可以覆盖此标志并设置为 true。"这意味着您的解决方案/解决方法是有效的。【参考方案2】:

我投了 nemesv 答案,因为它给了我一个关于正在发生的事情的解释。我有 MVC3 和 MVC4 项目,这让我发疯。

但是我有另一个解决方案。重写 Controller 类中的 Initialize 方法:

public abstract class BaseController : Controller

  protected override void Initialize(System.Web.Routing.RequestContext requestContext)
  
     string languageId = "en";
     try
       // all your code here. You have access to all the context information, 
       // like querystring values:
       string languageId = requestContext.HttpContext.Request.QueryString["lang"];
       Thread.CurrentThread.CurrentUICulture = 
          CultureInfo.CreateSpecificCulture(languageId);
     
     finally
     
       Thread.CurrentThread.CurrentUICulture = 
         CultureInfo.CreateSpecificCulture(languageId);
     

     base.Initialize(requestContext);
  

然后在您的项目中让您的控制器从 BaseController 继承,仅此而已,BaseController 调用会自动传递请求上下文。它适用于 MVC3 和 MVC4。

【讨论】:

这也适用于自定义模型绑定器吗?调用模型绑定器时是否正确设置了线程文化? 您的解决方案是 Alphonzo 的绝佳方法。它完全是 ExecuteCore() 的正确替代方法,并且适用于 MVC5。这是 Controller.Initialize 方法的 MSDN 文档:msdn.microsoft.com/en-us/library/… 很高兴知道,但它对我不起作用,因为我需要访问我的数据库上下文和一个会话变量,它们在 Initialize 被触发时尚未实例化。 BeginExecuteCore 为我完成了这项工作。【参考方案3】:

你也可以使用 BeginExecuteCore

protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)

    return base.BeginExecuteCore(callback, state);

【讨论】:

在 MVC 4 中效果很好。又好又简单。

以上是关于基类中的 ExecuteCore() 未在 MVC 4 beta 中触发的主要内容,如果未能解决你的问题,请参考以下文章

ThinkPHP 3.2 自定义基类 Model

pytest 不承认基类中的 PASSED 依赖项导致派生类中的 SKIPPED 测试

在使用基类中的方法时使用派生类中的属性?

基类中的 NUnit 和 [SetUp]

为啥 Type.GetFields() 不返回基类中的支持字段?

ASP.NET MVC中的Global.asax文件