11

Is there any possibility to find function like Page_Load? I have MVC application and I need run some code every page is loaded, or reloaded, or I call some controller. One shared function for everything classes?

I try Application_Start, but this execute only for first time application run. I search some like BeginRequest, but this function have been call several times, I need only first, when I load page and I need end function, like constructor and destructor for whole project.

Here is sample code.

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }  
}

document.ready isn't my case. And call function every controller is last option. The code must be executed before any other function have been called. And before all end, i need run end function. For example, at first I need created mysql connector shared for all classes. And at end I need close mysql connection.

user247702
  • 23,641
  • 15
  • 110
  • 157
MarTic
  • 665
  • 3
  • 10
  • 27
  • you can use Layout in mvc – Sirwan Afifi Oct 09 '13 at 08:51
  • 1
    Call the function in your Controller. This will be hit every time the page is loaded/reloaded. – Darren Oct 09 '13 at 08:52
  • 2
    Perhaps you're looking for an [`ActionFilter`](http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters)? `Application_BeginRequest` also fires for static files. – user247702 Oct 09 '13 at 08:55
  • BeginRequest is good idea, but i tryed it, and function has been called several times, no only once. – MarTic Oct 09 '13 at 09:00
  • @user1173536 I know, I was clarifying *why* it's called several times. – user247702 Oct 09 '13 at 09:05
  • if you want to fire a particular method every time then you can call the method in Index() action for that particular view – Ram Singh Oct 09 '13 at 09:06
  • 1
    as stated by @Stijn ActionFilter seems a very interesting option, allowing to keep lightweight Controllers, not hindering your code with a technically-focused hierarchy. – jbl Oct 09 '13 at 09:56
  • I second jbl's comment. ActionFilters can be mixed/matched/added/removed to one or more controllers without the rigid constraints of an inheritance hierarchy. – Triynko Aug 13 '15 at 14:47

2 Answers2

17

Make all your controllers inherit from a custom BaseController:

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext context)
    {
        base.OnActionExecuting(context);
        // your code here
    }
}

public class HomeController : BaseController // instead of Controller
{
    // ...
}
Jan Van Herck
  • 2,254
  • 17
  • 15
  • Yes, it's better solution. And do you know, how i set destructor in BaseController? – MarTic Oct 09 '13 at 09:28
  • Assuming you don't really mean "destructor" but "do something after the request is handled", you should use OnActionExecuted in the same way as OnActionExecuting. If you absolutely must do something when any controller is processed by the garbage collector, just define a ~BaseController() function as normal. Note that you have absolutely no control over when this function is being called. – Jan Van Herck Oct 09 '13 at 09:42
  • Is there official documentation on the Controller Lifecycle somewhere? What other methods are available to override? – styfle Jul 06 '18 at 12:54
  • @styfle, there is great documentation of the whole MVC pipeline here: https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/lifecycle-of-an-aspnet-mvc-5-application . Recommend downloading the PDF found on this page for a better view. – Howie May 29 '20 at 07:14
  • But what if you need Dependency Injection in your BaseController? And need an await for calling an API? The info from API should be used in all controllers. – Vekonomen Nov 26 '20 at 08:52
7

An update to Jan's answer. The onExecutingAction abstract method is public now not protected.

public virtual void OnActionExecuting(ActionExecutingContext context);

So, you can't use the protected access modifier when you override. Make it public instead.

public class BaseController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        base.OnActionExecuting(context);
    }
}
Qudus
  • 1,440
  • 2
  • 13
  • 22