Permanently disable AutoEventWireup - asp.net

I'm working on a project where performance is really important and i would like to disable AutoEventWireup permanently. The problem is in the fact that the page and control directives override the settings from web.config. Since there will be many collaborators on this project it will be impossible to expect everyone to disable it when creating new pages and controls (and it is true by default). Is it possible to somehow enforce this rule?
I hoped to solve this in a similar way as I did with the ViewState - setting the EnableViewState to false programmatically in the base page that all new pages inherit. But it seems there is no equivalent for AutoEventWireup.

Override SupportAutoEvents
public class BasePage : System.Web.UI.Page
{
public BasePage()
{
this.Init += (_o, _e) => {
this.Load += (o, e) => {
Response.Write("in page handler");
};
};
}
protected void Page_Load(object sender, EventArgs e)
{
// this handler is NOT assigned to the Load event
Response.Write("assigned by ASP .Net handler");
}
protected sealed override bool SupportAutoEvents
{
get
{
return false;
}
}
}

Create your own set of controls for each of the out of the box ones that you want to disable these properties for. Then set the two controls in the inherited versions to readonly.

Related

Event when adding a related page to a document

Apart from LogChange is there a more specific event that gets fired when adding/deleting a related page to a document ?
I want to be able to remove a page from cache when this happens
Have you tried using the global events defined by the CMS.DocumentEngine.RelationshipInfo.TYPEINFO.Events property? For example:
public class CustomRelationshipEvents : CMSLoaderAttribute
{
public override void Init()
{
RelationshipInfo.TYPEINFO.Events.Insert.After += Insert_After;
}
private void Insert_After(object sender, ObjectEventArgs e)
{
// Clear cache here
}
}
Then add your CustomRelationshipEvents attribute to an extension of Kentico's CMSModuleLoader class...

How to access Page classes and Usercontrols in code files for website projects

I am trying to convert an ASP.net web application into a website. One issue i am coming across is trying to access usercontrols and masterpages in my code files.
The code below shows a class i am using for a base class, it inherits from System.Web.UI.Page.
public class AdminBase : BasePage
{
DeniedAccess deniedAccessControl;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//All pages that inherit from this will have a denied access control which will display when an admin of one instance tries to access admin pages of a different instance
//which they don't have access to. This enables us to still use the built in web.config authroisation API
deniedAccessControl = (DeniedAccess)Page.LoadControl("~/App_Controls/DeniedAccess.ascx");
((MasterPage1)Master).MainContent.Controls.Add(deniedAccessControl);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (deniedAccessControl.ContentVisible)
{
foreach (Control control in ((MasterPage1)Master).MainContent.Controls)
{
//only sets to false if the control is set to true as it will error if you try to set a non visiual controls "Visible" property. E.g an sqldatasource control
if (control.GetType() != deniedAccessControl.GetType() && control.Visible)
control.Visible = false;
}
}
}
}
The "DeniedAccess" control is a user control i am dynamically adding if the user fails some custom authorization.
This worked fine when this was a web application as the DeniedAccess control was compiled into the same dll so i could access it from the code. Now that it is a website it cannot find the namespace/class as it is not in the App_Code folder.
Is what I'm trying to do possible in a website project? I can't seem to find a way and the only alternative i see is having to write this code for each individual page rather than use it on a base page.
I also get the same problem when trying to cast the master page to my "MasterPage1" class for the same reason, it can't find it so i cannot access it's properties.
I ended up creating two interfaces to solve this problem, as it wasn't a code behind file i couldn't just add a reference to the control/master page in the source.
I made my usercontrol inherit this interface
public interface IDeniedAccessControl
{
bool ContentVisible
{
get;
}
}
And my master page inherit this one
public interface IMasterPage
{
void AddControl(Control control);
ControlCollection MainContentControls
{
get;
}
}
I then made my usercontrol and master page implement there respective interface with the desired functionality.
Master page implementation:
public void AddControl(Control control)
{
ContentPlaceHolder1.Controls.Add(control);
}
public ControlCollection MainContentControls
{
get { return ContentPlaceHolder1.Controls; }
}
User control implementation:
bool IDeniedAccessControl.ContentVisible
{
get { return ContentASPxPanel.Visible; }
}
I could then use this on any code file. Below is how i edited my original code.
public class AdminBase : BasePage
{
IDeniedAccessControl deniedAccessControl;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//All pages that inherit from this will have a denied access control which will display when an admin of one instance tries to access admin pages of a different instance
//which they don't have access to. This enables us to still use the built in web.config authroisation API
deniedAccessControl = (IDeniedAccessControl)Page.LoadControl("~/App_Controls/DeniedAccess.ascx");
((IMasterPage)Master).AddControl((Control)deniedAccessControl);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (deniedAccessControl.ContentVisible)
{
foreach (Control control in ((IMasterPage)Master).MainContentControls)
{
//only sets to false if the control is set to true as it will error if you try to set a non visiual controls "Visible" property. E.g an sqldatasource control
if (control.GetType() != deniedAccessControl.GetType() && control.Visible)
control.Visible = false;
}
}
}
}

Custom Image Button control click handler not firing

I've got a bit of an issue with creating a new control based on ASP.NET's ImageButton control. Everything works as expected, except for the click handler that is being hooked up in the control's OnInit override. Basically, clicking the custom image button just refreshes the page, never hitting the handler.
Now, I know this is something stupid I've done or just not understood, but I can't for the life of me figure this out. All the articles, questions and forum posts I've found on event handling issues for controls is for child controls, rather than ones that inherit from existing control types and have their own predefined handlers.
The following code is what I've written:
public class WebPaymentButton : ImageButton
{
public string DisabledImageUrl { get; set; }
public string TermsAcceptClass { get; set; }
protected override void OnPreRender(EventArgs e)
{
Page.ClientScript.RegisterClientScriptResource(typeof (WebPaymentButton), "PaymentModule.Scripts.WebPaymentButtonScript.js");
}
protected override void OnInit(EventArgs e)
{
CssClass = "WebPaymentButton";
if (!string.IsNullOrWhiteSpace(TermsAcceptClass))
{
Attributes["data-TermsClass"] = TermsAcceptClass;
}
if (!string.IsNullOrWhiteSpace(DisabledImageUrl))
{
Attributes["data-DisabledImageUrl"] = ResolveUrl(DisabledImageUrl);
}
Click += WebPaymentButton_Click;
base.OnInit(e);
}
private void WebPaymentButton_Click(object sender, ImageClickEventArgs e)
{
HttpContext.Current.Response.Redirect("http://dummy_payment_page_in_place_of_code", true);
}
}
I've tried hooking the handler up in the OnLoad and also switching it to run after the base.OnInit/OnLoad calls. Nothing has solved the handler issue. Can anyone point me in the right direction?
In case it helps, here is the markup for the button on the page:
<pm:WebPaymentButton runat="server" ImageUrl="~/pay-now.png" DisabledImageUrl="~/not-pay-now.png" TermsAcceptClass="TermsCheckbox" ID="MainPayButton" />
Have you tried overriding the OnClick event handler instead of hooking up to a new event handler?
Remove the Click += WebPaymentButton_Click line from OnInit and remove the WebPaymentButton_Click function, then add the following code to your class instead:
protected override void OnClick(ImageClickEventArgs e)
{
base.OnClick(e);
HttpContext.Current.Response.Redirect("http://dummy_payment_page_in_place_of_code", true);
}

Can i unsubscribe to an event of BasePage from a page which inherits from BasePage in asp.net

I have a BasePage having common functionality required by all pages. I have defined a PreRender() event on page base. There are 2-3 pages which does not require this functionality. Can i unsubscribe to PreRender() event of BasePage from my .aspx page. I tried casting BasePage to Page
(PageBase as Page).PreRender -= OnPreRender(new EventArgs());
but it says PageBase is a type but is used as a variable. How to achieve this. Please suggest.
I am adding PreRender() event as follows:
public PageBase()
{
this.PreInit += new EventHandler(PageBase_PreInit);
this.PreRender += new EventHandler(PageBase_PreRender);
}
Your example looks close. What if you try:
base.Page.PreRender -= new EventHandler(Page_PreRender);
This assumes you added the event using:
base.Page.PreRender += new EventHandler(Page_PreRender);
Another option is override the OnPreRender method in your BasePage and use a protected field to check if it should be done. For the three pages, set it to false:
protected bool _useMyCustomPreRender = true;
protected override void OnPreRender(EventArgs e)
{
if (_useMyCustomPreRender)
{
// do my logic here
}
base.OnPreRender(e);
}

ASP.NET dynamically reassign controls in the control tree

Let's say I have a custom control that looks like this
<cc:MyControl runat="server" ID="myc" LinkControlID="NewParent" />
and, on the same page:
<asp:TextBox runat="server" ID="NewParent" />
What I would like to do is, from MyControl, change NewParent's parent so that it would be part of MyControl's Controls collection. When I try to do this, from OnInit, I get:
The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.
Which makes sense, but is there a way around this? I'm OK if NewParent remains the child of the Page as long as from MyControl I can somehow redirect the rendering to MyControl's control.
Can this be done? Thanks.
EDIT:
To clarify here's a mockup of MyControl:
public class MyControl : Panel
{
protected override void OnInit(System.EventArgs e)
{
base.OnInit(e);
if (!String.IsNullOrEmpty(LinkControlID))
{
Control link = Parent.FindControl(LinkControlID);
if (link != null)
{
Controls.Add(link);
}
}
}
public string LinkControlID { get; set; }
}
This assumes that MyControl and LinkControlID are placed on the same level in the tree hierarchy, which is OK in my case.
why don't you try adding it in Page_LoadComplete
myc.Controls.Add(NewParent);
I couldn't reproduce it, but as aman.tur suggested, have you tried another event? Overriding CreateChildControls() seems like the right place for it.
#TheVillageIdiot's suggestion worked for me:
protected void Page_Init(object sender, EventArgs e)
{
Page.LoadComplete += Page_LoadComplete;
}
private void Page_LoadComplete(object sender, EventArgs e)
{
if (InHeader)
{
Page.Header.Controls.Add(this);
}
}
Mind you, I had different requirements, but I don't think it should be much of an issue if you can access the new parent control from within your MyControl. The general format is to add an event listener on the Page to make changes on LoadComplete.

Resources