【问题标题】:ExecuteCore() in base class not fired in MVC 4 beta基类中的 ExecuteCore() 未在 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();
    }
}

【问题讨论】:

    标签: controller asp.net-mvc-4 base-class


    【解决方案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 中效果很好。又好又简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多