I need to remove an object from the PageHandler Header Controls collection in my page template.
I can use the below script to do so at the widget view level, however the one I need to remove has not yet been added at that point, so I need to move it right before it's consumed.
The only accessible place for it that I could find is in my template file - right before @Html.Section("head")
. I'm trying to remove the default canonical URL for this template only (some crazy routing stuff going on in this site... don't ask).
var pageHandler = this.ViewContext.HttpContext.Handler.GetPageHandler();
foreach (var c in pageHandler.Header.Controls)
{
if (c != null && c is System.Web.UI.HtmlControls.HtmlLink)
{
System.Web.UI.HtmlControls.HtmlLink mylink = (System.Web.UI.HtmlControls.HtmlLink)c;
if (mylink.Attributes["rel"] == "canonical")
{
pageHandler.Header.Controls.Remove(mylink);
}
}
}
When I try to use this in the template file inside the <head>
tag pageHandler.Header
is null.
1 - Am I accessing this object in the wrong way for this particular template level? If so, what's the proper object reference?
2 - Is it simply not set yet because of some behind-the-scenes page construction order in Sitefinity? If so, where could/should I handle accessing this object?
3 - Something else is going on entirely?
I AM NOT ASKING HOW TO FIX A NULL REFERENCE EXCEPTION
I understand that the object is null and am trying to find where in the Sitefinity viewmodel at this level this data might be found.
The canonical url is set in Page_PreRenderComplete event which fires after your code in the view has executed.
What I would do is create a new widget, e.g. CanonicalUrlRemover.
In its Index method find the Page object and subscribe to its PreRenderComplete event. Then in the event handler remove the canonical url.
public ActionResult Index()
{
var page = HttpContext.CurrentHandler.GetPageHandler();
page.PreRenderComplete += Page_PreRenderComplete;
return new EmptyResult();
}
private void Page_PreRenderComplete(object sender, System.EventArgs e)
{
var page = sender as System.Web.UI.Page;
if (page != null)
{
var headerControls = page.Header.Controls;
foreach (var c in headerControls)
{
if (c != null && c is System.Web.UI.HtmlControls.HtmlLink)
{
System.Web.UI.HtmlControls.HtmlLink mylink = (System.Web.UI.HtmlControls.HtmlLink)c;
if (mylink.Attributes["rel"] == "canonical")
{
headerControls.Remove(mylink);
}
}
}
}
}
Just drop the widget in this particular page template and you are good to go.