Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Override The Same Function On Multiple ASP.NET Pages (Render Function)

Take the following scenario. I have multiple ASPX pages. Login, Logout, Main, Messages, etc... They all inherit from System.Web.UI.Page of course. For all the pages, I want to override the Render method from the Page class. I could easily copy and paste the same code into each page like so:

protected override void Render(HtmlTextWriter writer)
{
     //Code Logic Here
}

But if I had many pages, lets say 20, maintaining the code in each page could get very time consuming and error prone.

That made me think a bit and I thought okay lets try this...override the function in each page but call a static function. That way changing the static function would result in a change for every page. Which works fine... But its not really nice and clean, having to override like that on every single page. Anybody have any ideas or thoughts on this one? Perhaps something simple I am overlooking? Thanks

EDIT: Some pages use the System.Web.UI.Page class and some pages inherit from another class called ModifiedPage which inherits and overridies other functions of the System.Web.UI.Page class. So its not as simple as inheriting all the pages from one class.

EDIT2: All pages need this behavior, some already derive from another class, and I am unable to change the implementation or inheritance hierarchy of that other class.

like image 565
Issa Fram Avatar asked Jan 26 '11 14:01

Issa Fram


2 Answers

Instead of inheriting from System.Web.UI.Page, have them all inherit from MyProject.MyBasePage which inherits from Page:

public abstract class MyBasePage : System.Web.UI.Page
{
    protected override void Render(HtmlTextWriter writer)
    {
        //Code Logic Here
    }
}

and...

public partial class MySpecificPage : MyBasePage
{
}

Edit

Clarification added to the question now points out the real puzzle - the pages which all need this common Render logic have different inheritance paths. That is more tricky in c#, and you won't be able to avoid at least a little bit of redundant plumbing code. There's plenty of different ways to handle this - here's one approach I have taken in the past:

1) Create an interface for this common functionality. For example, IOverrideRender:

public interface IOverrideRender
{
    void Register(OverrideRender render);
}

public delegate void OverrideRender(HtmlTextWriter writer, Action<HtmlTextWriter> original);

2) Each page which needs this functionality gets the interface and wires it like so:

public partial class MyPage : Page, IOverrideRender
{
    void IOverrideRender.Register(OverrideRender render)
    {
        this.overrideRender = render;
    }

    private OverrideRender overrideRender;

    protected override void Render(HtmlTextWriter writer)
    {
        if(overrideRender != nul)
        {
            overrideRender(writer, base.Render);
        }
        else
        {
            base.Render(writer);
        }
    }
}

3) In an HttpModule, check to see if the handler is IOverrideRender and if so, pass in your custom render method:

public class OverrideRenderModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += this.HandlePreRequestExecute;
    }

    private void HandlePreRequestExecute(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
        IOverrideRender overridable = app.Context.CurrentHandler as IOverrideRender;
        if(overridable != null)
        {
            overridable.Register(
                (writer, original) => {
                    writer.Write("Hello world"); //custom write
                    original(writer); //calls base.Render
            });
        }
    }
}
like image 72
Rex M Avatar answered Nov 14 '22 05:11

Rex M


You should create a BasePage which inherits from System.Web.UI.Page. Within the BasePage you could override the Render method and then have all your pages inherit from BasePage.

like image 1
dparker Avatar answered Nov 14 '22 04:11

dparker