How to do something firstly when the asp.net server start - asp.net

I need an interface that can be run firstly when the application start.
We can write some code in Application_Start of global.ascx.
Is there any other method to finish it after some configurations in web.config,i don't wanna write any code in global.ascx
You know,we can implement the Interface 'IHttpModule' to diy each request.
But the interface is not fix to application start.
which one is i wanna?
Thanks

A HttpModule is something that handles requests, and is not directly related to the lifetime of an application. Even if it's reusable, it may not survive during the whole lifetime of an application. The Global.asax file, on the other hand, becomes a subclass of HttpApplication, which indeed is a class that relates to the startup, shutdown and lifetime of a web application. According to MSDN, Global.asax is the file to put startup and shutdown code.

You can use the Init method of your module. It fires more or less around the same time as the Application_Start for the Global.asax.

Related

Getting the Server in Global.asax in ASP.NET MVC 4

When our ASP.NET MVC 4 app starts, we need to set a property on a Log4Net Appender which depends on what the site is.
Is there a way to get the 'http://www.site.com' part some time in the sites initial load, perhaps in Global.asax?
Overview:
If the server is www.site2.com then set the Appender.SomeValue = "555"
If the server is www.site.com then set the Appender.SomeValue = "123"
Because many sites will point to the same code base we don't know what we need to set Appender.SomeValue to until it runs.
I think methods in Global.asax would run, only in response to a request. And almost everywhere inside the ASP.NET, you have access to HttpContext.Current.Request.Url.
Also there is a method that runs way before Application_Start, and that is a method decorated with PreApplicationStartMethodAttribute attribute.
One approach is to use WMI (Windows Management Instrumentation) to get access to the current website, it's bindings and thus the site address.
Pre-application start is more limited as it is run before the application is started, more for initializing di containers. To be safe I would put the code in a new static method defined in global.asax.cs that is called by application_start method at this point access to HttpContext.Current.request.Url should be safe

How do I get a service to start from global.asax without having to invoke it?

I have a simple app where I use global.asax to map a serviceroute to a wcf service through a custom servicehostfactory in Application_Start. The constructor of that service does some initial processing to set up the service which takes a bit of time.
I need this constructor to fire when its serviceroute is added automatically. I tried creating a clientchannel from global.asax and making a dummy call to spin up the service, but discovered the service isn't up yet -- it seems application_start has to return?
So how do I get the constructor of the service to fire when first mapped through global.asax without having to manually hit the service? Unfortunately AppFabric isn't an option for us, so I can't just use it's built-in autostart..
UPDATE
I was asked for a bit more detail;
This is like a routing management service. So I have Service1 -- it gets added as a serviceroute in global.asax. Now I have http://localhost/Service1
Inside Service1 I have a method called 'addServiceRoute'. When called, it also registers a route for Service2. Now I have http://localhost/Service1/Service2.
My initial solution from global.asax was to build a channelfactory to http://localhost/service1 but that wouldn't work. Service1 wasn't up yet and wouldn't come up till Application_Start returned (Still not sure why?). So then I thought I'd cheat and move that initial addserviceroute call to the constructor of service1. Also didn't work.
It was mentioned that this shouldnt be in the constructor -- i agree, this is just testing code.
A singleton was also mentioned, which might be ok, but I intend to have more than one instance of Service1 on a machine (in the same app pool) so I don't think that'll work?
** UPDATE #2 **
I was asked for sample code.. here it is from global.asax (trimmed a bit for brevity).. So http://localhost/Test DOES come up.. But if I have to use appfabric to warm up Test and get its constructor to fire, then don't I need Test.svc or something? How do I get appfabric to even see this service exists?
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
RouteTable.Routes.Add(
new ServiceRoute("Test", new MyServiceHostFactory(ITestService, BindingType.BasicHttpBinding, true), TestService));
}
What you describe requires singleton service (something you should avoid) because normally each call or session gets a new instance = a new call to constructor. In self hosted WCF service you can instantiate singleton service instance and pass it to ServiceHost constructor. In case of IIS hosted service used together with ServiceRoute you can try to create your own class derived from ServiceHostFactory and pass created service instance as a parameter to its constructor. In this factory class implement CreateServiceHost method and pass that existing service instance into ServiceHost constructor. To make this work your service class must still be handled as singleton through service behavior.
Btw. constructor should not do any time consuming operation. Constructor is for constructing object not for initializing infrastructure. Using constructor for such initialization is bad practice in the first place.
AppFabric autostart is what I would recommend - even though you say you cannot use it - this is the problem it was meant to solve (warming up your service).
As an alternative before AppFabric existed, you would have to use a scheduled task (a.k.a cron job) with an executable that calls into the service you want initialized. The way AppFabric autostart works is by using named pipes (net.pipe) to trigger the warm up - but it just does this exact thing when the service is recycled. The difference between the scheduled task approach and the AppFabric autostart is that the scheduled task doesn't know when your application pool has been recycled - you would need to poll your service periodically to keep it warm.
Alternatively you could consider hosting your WCF application outside of IIS via self-hosting. This would avoid the warm-up issue, but you wouldn't achieve many of the benefits of the IIS hosted container. See HttpSelfHostServer in the new MVC Web API or review using a standard ServiceHost.

What code whould be placed in the application_start and the session_start events in global.asax?

Can you give an example of what might be best suited to place in the Application_Start and Session_Start subroutines?
I know when each subroutine is called.
Application_Start when the first user first accesses the web application.
Session_Start when a user opens a session with the application.
But what code belongs in each of these subroutines. What should the code in each subroutine do?
Just any examples? Well, in an MVC site the routes are registered in Application_Start. That's also a good place to initialize an IoC container such as StructureMap. Maybe initialize some singletons you have in your application if you want them to be readily available rather than late-bound when a user accesses them (like if they have a high initialization cost and you'd rather do one slow initial hit on the website yourself than bother a customer or two with it).
Session_Start is generally used less often, but could be a good place for per-user (or per-session, realistically) tracking of some kind.
Application_Start is often used to initialize application wide settings which need to be done once per application domain like registering object containers, reading some config initialization values, ... In Session_Start you could place some code which is tied to the specific user who started the session.
Be careful with exception handling in Application_Start. In IIS7 Integrated mode you won't have the response object or HTTPContext. See this thread: Request is not available in this context

Advanced: How many times does HttpModule Init() method get called during application's life?

Web application initialization is as follows:
As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a HttpApplication (defined in global.asax codebehind).
When this new instance is created it's initialization happens that also checks all configured HTTP modules.
All modules are then instantiated and put in the application's Modules collection (of type HttpModuleCollection)
modules are looped through and their Init() method is called (when they register for request events)
As far as I understand it the above scenario happens when a web application is started/initialized (hence application start event).
What happens with modules?
Are they (re)instatiated on each request or reused from the Modules property on each consecutive request while the web application is alive? As I understand IIS and Asp.net they are reused through the whole life of a web application.
If they are reused, can we assume that their Init() method is actually a pseudo event handler for application start event? The thing is we can't attach to application level events within http modules. But if they are being reused we could use Init() as application start event and do whatever we'd put in global.asax instead.
Question
Can we assume that module's Init() method is called only on application start event? Could we use this assumption to i.e. register routes for applications whose global.asax codebehind we can't change? web.config is usually accessible and we can change it the way we want.
Would this actually work?
Additional info
We can check HttpApplication code and check its InitModulesCommon() method. This one actually calls Init() of each registered HTTP module. What is more interesting is that this method is only used by InitIntegratedModules() and InitModules() methods. Which are both used only in HttpApplication.InitInternal() method. This is the basis of my assumptions, but I would like to know whether someone has abused IHttpModule.Init() for application start event.
Init() is called only once (per HttpApplication instance)
After I tested this the inner workings of IHttpModule initialization are as follows:
Every IHttpModule is initialized at web application start by instatiating and a call to Init() method
HttpApplication stores all module instances in its Modules property
Modules are then reused for the whole life of an HttpApplication and are not discarded/reinitialized as long as the application is alive
So the best outcome is
You can't attach an IHttpModule to application level events, but you can use its Init() method as pseudo application start event delegate. Inside it you can execute any code that you'd usually put inside Application_Start delegate in your Global.asax.
You can also read detailed information about it in my blog post.
But be careful in real-life web server environment
But IIS uses something called application pools. And each pool can have an arbitrary number of HttpApplication instances. Yes multiple. Application starting creates all these instances. Every one of them initializes their own list of modules but only the first one executes the Application_OnStart event handler.
So whenever your module modifies some common shared resource, you should take extra measures to indicate that the first module has done that and others won't do it again. Read an additional blog post about it that will show you how and when to use thread locking with your module to make it actually act as an Application_OnStart event handler. BTW: It's also possible to handle Application_OnEnd event if you need to. ;)
Detailed blog post links
Writing a custom IHttpModule that handles Application_OnStart event
How to correctly use IHttpModule to handle Application_OnStart event
Application_Start is only run once for the lifetime of your application.
IHttpModule.Init is run for each instance of HttpApplication, before request processing begins. See the walkthrough. Init is where you can register events used to process the request.
An instance of HttpApplication can be reused for multiple requests. ASP.Net pools HttpApplication objects, so the Init will be called once for every new instance of HttpApplication

Does Application_Start block all incoming requests

I have some code that initializes a static singleton class, which is needed by all requests. Therefore I thought I could add it to global.asax Application_Start. Can I be 100% sure that all requests will block while Application_Start is loading to guarantee that all the requests will have access to it?
Thanks a lot
Jeeji
Short answer: yes.
Application_Start:
Called when the first resource (such
as a page) in an ASP.NET application
is requested. The Application_Start
method is called only one time during
the life cycle of an application. You
can use this method to perform startup
tasks such as loading data into the
cache and initializing static values.
You should set only static data during
application start. Do not set any
instance data because it will be
available only to the first instance
of the HttpApplication class that is
created.
http://msdn.microsoft.com/en-us/library/ms178473.aspx

Resources