Подтвердить что ты не робот

ExecuteCore() в базовом классе, не запущенном в бета-версии MVC 4

У меня есть класс базового контроллера:

И весь мой другой контроллер наследует этот BaseClass, как этот

Все это отлично работает в MVC3 (снова тест сегодня, он действительно работает), но кажется, что ExecuteCore в BaseController больше не запускается в бета-версии MVC 4.

Любая идея? Или что-то огромное изменилось под капотом? Большое спасибо.

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();
    }
}
4b9b3361

Ответ 1

Я смог воспроизвести вашу проблему. Кажется, что использование ExecuteCore изменено. Но я не нашел никакой информации об этом. Я предполагаю, что это связано с тем, что теперь Controller реализует IAsyncController не AsyncController.

Однако я нашел обходное решение, чтобы получить старое поведение с MVC4:

Добавьте это в BaseContoller:

protected override bool DisableAsyncSupport
{
    get { return true; }
}

На странице MSDN для DisableAsyncSupport (добавьте меня мной):

Этот флаг предназначен для обратной совместимости. ASP.NET MVC 4. позволяет контроллеру поддерживать асинхронные шаблоны. Это означает, что ExecuteCore не вызывается на производные классы. Производные классы могут переопределить этот флаг и установить на true, если они все еще нуждаются в ExecuteCore для вызова.

Ответ 2

Я проголосовал за nemesv, потому что он дал мне объяснение о том, что происходит. У меня есть проекты MVC3 и MVC4, и это меня раздражало.

Однако у меня есть другое решение. Переопределить метод Initialize в классе Controller:

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.

Ответ 3

Вы также можете использовать BeginExecuteCore

protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
    return base.BeginExecuteCore(callback, state);
}