Recuperer la page sans la master page associé

Contenu du snippet

Dans la meme optique que cette source : http://www.aspfr.com/code.aspx?ID=34070, j'avais besoin de recuperer le contenu de la page sans le masterpage associé.

imaginons que vous avez une page default.aspx et une master page, default.master, dans default.master vous avez des UserControl un peu de partout car commun a toutes les pages, et dans default.aspx vous avez juste le texte "bonjour le monde". Quand vous allez sur http://localhost/default.aspx, le texte "bonjour le monde" ainsi que tous les userControl du master apparait. Ce que vous avez envie vous c'est de recuperer juste "bonjour le monde", donc annuler la masterPage.

La solution est assez simple, il suffit de créer une classe dérivant de System.Web.UI.page, et ensuite de faire dériver vos page de cette nouvelle classe.

Qu'apporte en plus cette nouvelle classe ?

2 propriétés :
RenderOnlyPage (boolean) : si elle est vrai, alors la page ne comportera pas le masterpage
RenderOnlyOneContentPlaceHolder (string) : il faut spécifier le contentPlaceHolderID que vous voulez afficher, par défaut la propriété est à string.Empty, et cela affichera tout les ContentPlaceHolder

La classe fonctionne simplement, dans le page_init, je regarde si on doit afficher le master, si non, je vais parcourir recursivement tout les controls de la page, et je vais supprimer tout ce qui n'est pas ContentPlaceHolder.

Comme sur ma précedente source j'ai surchargé VerifyRenderingInServerForm pour ne pas être embeté avec l'absence de balise form.

Pour se servir de la classe c'est bien simple, faites dériver vos pages de CSLib.Web.UI.Page

public partial class Default : CSLib.Web.UI.Page
{

protected void page_PreInit(object sender, EventArgs e)
{
Boolean RenderOnlyPage = false;
Boolean.TryParse(Request.QueryString["nomaster"], out RenderOnlyPage);
this.RenderOnlyPage = RenderOnlyPage;
this.RenderOnlyOneContentPlaceHolder = "ContentPlaceHolder1";
}
}

dans ce cas, si ma requete est default.aspx la page entiere va s'afficher (avec la masterpage) et si la requete est default.aspx?nomaster=true, la page s'affichera sans le masterpage :)

Source / Exemple :


using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;

namespace CSLib.Web.UI
{
   public class Page : System.Web.UI.Page
   {

       #region "Constructor"
       public Page()
        {
            this.Init += new EventHandler(Page_Init);
        }
       #endregion

       #region "Property"

       private Boolean renderOnlyPage = false;
       /// <summary>
       /// if true, the page would render only ContentPlaceHolder
       /// </summary>
       public Boolean RenderOnlyPage
        {
            get { return renderOnlyPage; }
            set { renderOnlyPage = value; }
        }

       private string renderOnlyOneContentPlaceHolder = string.Empty ;
       public string RenderOnlyOneContentPlaceHolder
       {
            get { return renderOnlyOneContentPlaceHolder; }
            set { renderOnlyOneContentPlaceHolder = value; }
       }
	

       #endregion

       /// <summary>
       /// List of ContentPlaceHolder
       /// </summary>
       private List<Control> _Control = new List<Control>();

        void Page_Init(object sender, EventArgs e)
        {  
            if (RenderOnlyPage)
            {
                // parcours récursif sur tous les controles de la page
                CheckContentPlaceHolderRecursive(this);

                // suppression de tous les controles de la page
                // pour ensuite rajouter nos contentPlaceHolder
                this.Controls.Clear();
                foreach (Control c in _Control)
                    this.Controls.Add(c);
            }
        }

       /// <summary>
       /// fonction recursive, qui fouille dans les controles de la page pour trouver 
       /// un ContentPlaceHolder
       /// </summary>
       /// <param name="control"></param>
        private void CheckContentPlaceHolderRecursive(Control control)
        {
            if (control is System.Web.UI.WebControls.ContentPlaceHolder)
            {
                if (RenderOnlyOneContentPlaceHolder == string.Empty )
                    _Control.Add(control);
                else if (control.ID == RenderOnlyOneContentPlaceHolder)
                    _Control.Add(control);
            }
            else if (control.Controls.Count > 0)
                foreach (Control c in control.Controls)
                    CheckContentPlaceHolderRecursive(c);
        }

       /// <summary>
       /// Cette méthode déclenche un evenement, si un control ayant besoin d'une balise form
       /// (c'est le cas des controles avec postback) est absent. 
       /// En surchargeant cette méthode on passe outre cette limitation.
       /// </summary>
       /// <param name="control"></param>
       public override void VerifyRenderingInServerForm(Control control)
        {
            if (!RenderOnlyPage)
                base.VerifyRenderingInServerForm(control);
        }
    }
}

Conclusion :


tout commentaire est bon à prendre :)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.