Add Application Start event handler manually in constructor - c#

In Global, as an alternative to the application AutoEventWireups, it seems that events are exposed for most of the underlying Application events (BeginRequest, AuthorizeRequest, Error, etc), as well as a set of asynch methods like AddOnBeginRequestAsync etc. However, I cannot find an equivalent event for ApplicationStart!
So my question is, is there anyway to subscribe to the 'same' event that the AutoEventWireup method Application_(On)Start is hooked into?
public class Global : HttpApplication
{
public Global()
{
// I can do this ...
base.BeginRequest += new EventHandler(Global_BeginRequest);
// Or even AddOnBeginRequestAsync();
// But how can I do this?
base.ApplicationStart += new EventHandler(GlobalApplication_Start);
}
protected void Global_BeginRequest(object sender, EventArgs e)
{
// ...
}
protected void Global_ApplicationStart(object sender, EventArgs e)
{
// ...
}
}
(Out of interest ... is there a way to switch off the AutoEventWireups in Global.asax?. Using the AutoEventWireup = "false" attribute only seems to work on aspx pages)
Edit - it seems that ApplicationStart and ApplicationEnd "are special methods that do not represent HttpApplication events". So I might be barking up the wrong tree entirely.
Edit
Re : Why would I need this? Unfortunately, a corporate customer has a framework in place whereby new apps need to inherit their custom HttpApplication class, and FWR, their HttpApplication had already implemented the autowireup Application_(On)Start, meaning that I needed to find another way to override the Framework wireup, so that I can Bootstrap my IoC container and Automapper maps. As per Lloyd's answer, I could also bootstrap in the ctor or Init() as well, although this isn't quite the same. Ultimately I was able to change the corporate framework to allow multiple subscriptions.

You could override Init:
public class MyApplication : HttpApplication
{
public override void Init()
{
base.Init();
}
}
However your constructor could also work just as well.

Be really careful with the Init method.
Using Init method for code that you want to be executed once in the Application lifecycle is a bad option as the Init method is called once for every instance of the HttpApplication...
As you said ApplicationStart and ApplicationEnd are special methods that do not represent HttpApplication events but they work in a similar fashion to the Page events when the AutoEventWireups is set to true..
After jumping to the .NET source code i found that the HttpApplicationFactory class looks for a method named "Application_OnStart" or "Application_Start" in the Global.asax file and then invokes it using reflection => ReflectOnMethodInfoIfItLooksLikeEventHandler().
Check out my question about a similar subject: HttpApplication.Start event does not exist

Related

External class to run code on another page

I want to create a reference for button click event which happens on another page in UWP project.
Page one (witch button):
private void Button_ItemClick(object sender, ItemClickEventArgs e)
{
// some code to reference to class
}
Class (in external file)
public static void DoSomething()
{
// Do something on Page 2 or run void on page 2
}
If the method is static, you can call it without an instance of the class. Suppose the method is defined in class OtherPage. You could then just do:
private void Button_ItemClick(object sender, ItemClickEventArgs e)
{
OtherPage.DoSomething();
}
In case the method is not static, you cannot easily do that, because there is only one Page instance in memory at a given time, when you have just one navigation Frame. It would make sense to put the method into a service class that would have a singleton instance and you could call it from anywhere. You can use MVVM framework like MvvmLight or MvvmCross to make this easier. These frameworks also maintain navigation stack of pages and their view models so you can potentially access view model instances in the navigation backstack.

How do I make Umbraco play nice with NWebSec's built in CSP Report event handler?

I'm working on a website which uses the Umbraco CMS version 7. I'm using NWebSec to implement a CSP header on the website. NWebSec has built in functionality to raise a .Net event when there's a CSP violation. Normally you'd catch that event with something like this:
protected void NWebSecHttpHeaderSecurityModule_CspViolationReported(object sender, CspViolationReportEventArgs e)
{
var report = e.ViolationReport;
var serializedReport = JsonConvert.SerializeObject(report.Details);
// Do a thing with the report
}
in the Global.asax.cs file. But so far as I can tell, Umbraco preempts the Global.asax.cs file, and it eats any event that's thrown. I have a file with a few custom event handlers like:
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
to handle the standard pieces of application startup code that would normally be in the Global.asax.cs file, but putting the NWebSec event handler in that same file doens't work. Presumably it's because it's using the .Net event handler syntax rather than whatever Umbraco replaces it with.
How do I access the events thrown by NWebSec?
the Global.asax class inherits from UmbracoApplication so no, you can't use that. There are a number of reasons for this including enabling the ability to "run" Umbraco outside of the web context - i.e. in a console application).
After reviewing the available documentation on the NWebSec documentation website, I don't think you can just place your NWebSecHttpHeaderSecurityModule_CspViolationReported event handler method in the class, you will need to wire it up as well. It should probably look something like this:
public class MyGlobalEventHandler : ApplicationEventHandler {
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var nWebSecHttpHeaderSecurityModule = umbracoApplication.Modules["NWebSecHttpHeaderSecurityModule"] as HttpHeaderSecurityModule;
if (nWebSecHttpHeaderSecurityModule != null) {
nWebSecHttpHeaderSecurityModule.CspViolationReported += NWebSecHttpHeaderSecurityModule_CspViolationReported;
}
base.ApplicationStarted(umbracoApplication, applicationContext);
}
protected void NWebSecHttpHeaderSecurityModule_CspViolationReported(object sender, CspViolationReportEventArgs e)
{
var report = e.ViolationReport;
var serializedReport = JsonConvert.SerializeObject(report.Details);
// Do a thing with the report
}
}
If you're using a newer version of Umbraco that supports OWIN (7.3.0), you could use the NWebsec.Owin library which may give you a better result and more flexibility perhaps.

Global.asax magic functions

When creating an ASP.NET Mvc project in Visual Studio, a Global.asax & Global.asax.cs will be created. In this .cs file you will find the standard Application_Start method.
My question is the following, how is this function called? because it is not a override. So my guess is that this method name is by convention. The same goes for the Application_Error method.
I want to know where these methods are hooked. Because I write those methods (not override them) I couldn't find any documentation on them in MSDN. (I found this page but it only tells you to hook to the Error event and shows a Application_Error(object sender, EventArgs e) but not how the Event and the method are linked.)
//Magicly called at startup
protected void Application_Start()
{
//Omitted
}
//Magicly linked with the Error event
protected void Application_Error(object sender, EventArgs e)
{
//Omitted
}
It isn't really magical.. the ASP.NET Pipeline wires all of this up.
You can see the documentation regarding this here.
Specifically you will be interested in the parts below:
An HttpApplication object is assigned to the request.
Which consists of a list of events that are fired and in what order.
There are links all over that page (too many to contain here) that link off to various other pages with even more information.
ASP.NET automatically binds application events to handlers in the
Global.asax file using the naming convention Application_event, such
as Application_BeginRequest. This is similar to the way that ASP.NET
page methods are automatically bound to events, such as the page's
Page_Load event.
Source: http://msdn.microsoft.com/en-us/library/ms178473.aspx
To demystify the 'magic' of the accepted answer, the ASP.Net pipeline is automagically binding the HttpApplication events to the methods with the Application_EventName in the class. If (much like me) you would rather see the events explicitly bound to a handler these can be bound by overriding HttpApplication.Init() and Visual Studio will generate the handler method with the correct signature.
public override void Init()
{
this.BeginRequest += MvcAppliction_BeginRequest;
}
private void MvcApplication_BeginRequest(object sender, EventArgs e)
{
...
}
There is an example of this method of binding events
ASP.Net itself creates it. Here is the flow as per MSDN -
User requests an application resource from the Web server.
ASP.NET receives the first request for the application.
ASP.NET core objects are created for each request.
An HttpApplication object is assigned to the request. In this step Global.asax will be processed and events will be associated automatically.
The request is processed by the HttpApplication pipeline. In this step the HttpApplication Global events are raised.
Here is the reference - ASP.Net Application Life Cycle.
From the reference - ASP.NET automatically binds application events to handlers in the Global.asax file using the naming convention Application_event, such as Application_BeginRequest.

Inherited Global.asax and Application_Start issue

I am trying to inherite a base global.asax class to create my custom global.asax class. But my custome inherited global class does not work properly. Its Application_Start wont been called.
Anyone knows whey?
public class BaseGlobal : HttpApplication
{
protected void Application_Start(Object sender, EventArgs e)
{
log4net.Config.XmlConfigurator.Configure();
Logger.Warn("Portal Started"); //I can find it log file
}
......
}
public class MyGlobal : BaseGlobal
{
new protected void Application_Start(Object sender, EventArgs e)
{
base.Application_Start(sender,e);
Logger.Warn("Portal Started 2"); // Can not find it in log file
}
}
<%# Application Codebehind="Global.asax.cs" Inherits="Membership_ABC.MyGlobal" Language="C#" %>
In the log file, I could not find "Portal started 2" but just "Portal Started".
Any ideas?
On startup of an application, the runtime takes the HttpApplication descendant that is pointed out by the Global.asax file, and creates an instance of it. The runtime does not know or care how the class got to be descended from HttpApplication, it just cares that it is, in fact a descendant.
After that it start calling method on it, treating it as a regular HttpApplication object. Since the new modifier effectively breaks the inheritance chain (it's just a new method that happens to share the old methods name) it is not called, but instead the method of the parent class is called. Basically you have this situation (pseudocode):
HttpApplication httpApp = new MyGlobal();
httpApp.Application_Start(..)
// ^^^ calls BaseGlobal.Application_Start(..)
//because the is not an unbroken chain from HttpApplication to MyGlobal
This is an example and consequence of the Brittle Base Class problem, a topic about which Eric Lippert has written in depth.
The solution is to declare the function virtual in the base class and then override it in the child class.
But as you can't edit base class to declare the Application_Start method virtual, it won't work :
Is it possible to override a non-virtual method?
The accepted answer gives an example that matches your case.

IService interface for calling services. One proxy per method or a global class level proxy

I am consuming WCF services from a Silverlight application (MVVM) and windows phone. I have a Service class (Auto-generated) and one IServiceRepository looks like the following
public interface IServiceRepository
{
event EventHandler<SomeEventArgs> GetDataCompleted;
void Data GetData();
// 10 more methods for fetching different data.
}
My SerViceRepository looks like the following
public class ServiceRepository : IServiceRepository
{
public event EventHandler<SomeEventArgs> GetDataCompleted;
public void Data GetData()
{
var proxy = new ActualServiceRefClient();
proxy.GetDataCompleted += PrivateGetDataCompleted;
proy.GetDatAsync();
}
private void PrivateGetDataCompleted(object s, SomeEventArgs e)
{
// Error check and all
if(GetDataCompleted != null)
GetDataCompleted(this, new SomeEventArgs(...));
}
}
I am calling this methods from my ViewModels. Now my questions are ...
Right now I am creating the proxy
class and attaching event handler
with it in every method. Should I do
it in the constructor of
ServiceRepository? As I said I have
around 10 to 12 service methods to
call.
Should I unregister the event handler in the completed method?
I'm not sure it matters where it goes. If you have just one one actual service method you are calling, putting the event wiring in the constructor makes sense. If there is one actual service method for each of the 10 data methods in your service repository, then it makes more sense to have them wired up in each of the 10-12 individual methods.
It depends. If you are keeping an instance of the Service Repository around, making several calls to it, then you should either move the event wiring to the constructor, or make sure you don't re-wire the event handler on each call. Alternatively, you CAN unregister as you said, but I think it's best to register those event handlers once for the lifetime of the object. If you are simply creating a new instance of your Service Repository for each can, there is no need to unregister the event handlers.
Hope this helps!

Categories