views:

518

answers:

3

I think somewere I saw an example about this but can not find it anymore:

Is there was a way to override a Page_Init() event on a global basis without creating a new MyCustomPage class inherited from Page?

I was in the hope that there were some way to make global overrides to Page without subclassing Page (without the need to inherith my pages from the subclass). I was thinking about something about the lines of Global.asax, but for Page.

This is the code I want to be run at PreInit in every page:

' Change Culture's ShortDate to "dd/mmm/yyyy" for es-MX.
If CultureInfo.CurrentCulture.Name = "es-MX" Then
    Dim info As CultureInfo = CultureInfo.CurrentCulture.Clone
    info.DateTimeFormat.ShortDatePattern = "dd/MMM/yyyy"
    System.Threading.Thread.CurrentThread.CurrentCulture = info
    info = Nothing
End If

Thanks in advance for your time.

Edit:

As of today, there have been 2 perfectly good solutions (for my case) offered below. I have selected one of those as accepted answer even I will be currently using the other solution. This is because the one I will be using was offered as a comment by @Simon to this question.

The solution was to place my code in Global.asax as:

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)

    ' Configure ShortDatePattern as "dd/MMM/yyyy" for es-MX to avoid month-day confusions when both are numeric.
    If CultureInfo.CurrentCulture.Name = "es-MX" Then
        Dim oCultureInfo As CultureInfo = CultureInfo.CurrentCulture.Clone
        oCultureInfo.DateTimeFormat.ShortDatePattern = "dd/MMM/yyyy"
        System.Threading.Thread.CurrentThread.CurrentCulture = oCultureInfo
        oCultureInfo = Nothing
    End If

End Sub

In my question I asked how to override Page_Init() without sub-classing Page. This seemed to cause some confusion. The reason is I am creating a project template with lot's of typically required functionality already in place (as User Admin, Rights Management, etc.).

For projects created with this template, I want to default to es-MX Culture and to modify ShortDatePattern to display months in abbreviated month names. As this is a project template I want to save my programmers from the need to implement their pages inheriting from a custom class. It just feels "weird" to me to imposing sub-classing for pages at this (project template) level.

The other solution. The one I marked as accepted was provided by @Ishtar. I have already implemented it and it works perfectly and falls within my needs. The only thing missing in the example code he provided is the need to call MyBase.OnInit(e).

I want to thank everyone who offered solutions and comments and a very special thank you to @Ishtar who provided an initial answer and stayed with this subject as I rejected it for my needs. Then he provided a second answer who proved right (the one marked as accepted).

A: 

You can write custom class which derives from System.Web.UI.Page and there you overide the method

public class CultureBasePage : System.Web.UI.Page
{

protected overide InitializeCulture(object sender, EventArgs e)
{

// set thread culture and ui culture here

base.InitializeCulture(sender, e);
}

}

then set your pages to derive from this class

public class _Default : CultureBasePage {}

If you dont need code-behind file you can set this also in aspx file:

<%@ Page Language="C#" Inherits="CultureBasePage" %>
Jan Remunda
Thank you Ishtar. I already knew that. My question specifies WITHOUT creating a custom class.
vmarquez
So, if you only want to set the culture, you can do this e.g. in global.asax in Application_BeginRequest method. You can also use control adapter for page, but it's not very good solution. Another way to overide page methods probably don't exists.
Jan Remunda
@Ishtar: Setting the culture was not the question. I am aready setting the Culture at Web.config. I will update my question to be more clear.
vmarquez
+2  A: 

Why are you trying to avoid inheriting from Page?

Your question is somewhat self-contradictory... The phrase "override Page_Init" implies the inheritance you are trying to avoid. Two options:

1) Do the task in a BeginRequest handler as Simon suggestions. 2) Create a new HttpHandler to use rather than Page. You may be able to encapsulate a Page object, but I don't think you can call Page.ProcessRequest directly, so this may be pointless.

Bryan
@Bryan: The why is just for convenience. Subclassing for just this small requirement seems a little too much. I wil check if the culture has been already loaded from Web.config at BeguinRequest. It it is the case, then I can place my code directly at Global.asax and avoid the subclassing.
vmarquez
In that case you should create a custom HttpModule. Global.asax is mostly for legacy support.
Bryan
@Bryan: Creating a custom HttpModule is my last resort. For now, I have verified customizing culture formats works perfectly at Application_BeginRequest in Global.asax.
vmarquez
I think you are not realizing how easy it is to create a new HttpModule! http://codebetter.com/blogs/karlseguin/archive/2006/06/12/146356.aspx
Bryan
@Bryan. I do realize it is easy. It is my last resort just because I find it easier to implement it in Global.asax. For my project needs (a project template specific for VS 2005 / .NET 2.0) is sufficient.
vmarquez
+2  A: 

Another one way to do this is using Page Adapter

public class TestPageAdapter : System.Web.UI.Adapters.PageAdapter
{
    protected override void OnInit(EventArgs e)
    {

        if (Thread.CurrentThread.CurrentCulture.Name == "es-MX")
        {
            CultureInfo info = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
            info.DateTimeFormat.ShortDatePattern = "dd/MMM/yyyy";
            System.Threading.Thread.CurrentThread.CurrentCulture = info;
            info = null;
        }
    }    
}

then register your PageAdapter class in App_Browsers/all.browser

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.Page" adapterType="TestPageAdapter" />
    </controlAdapters>
  </browser>  
</browsers>

it will runn on every page init.

Jan Remunda
@Ishtar: PageAdapters! I have to confess I have read about that in the past but never tried it. I will look at it for sure. I will let you know how it goes.
vmarquez
@Ishtar, I have tested your solution and it works perfectly. The only missing part was to call MyBase.OnInit(e). In my case, I called it just at the start of OnInit override. Thank you.
vmarquez