How to cache user controls that are inside code blocks? - c#

I have an aspx webpage with embedded code block that displays one of the two instances of the same user control. Simplified code:
<form id="form1" runat="server">
<div>
<%if (true)
{ %>
<UC:UserControl runat="server" ID="ucFirst"></UC:UserControl>
<%}
else
{ %>
<UC:UserControl runat="server" ID="ucSecond"></UC:UserControl>
<%} %>
</div>
</form>
Registered user control is cached:
<%# OutputCache Duration="60" VaryByParam="none" %>
However, only ucFirst gets cached, while ucSecond goes through Page_Load and Page_PreRender each time I refresh the page, even though it doesn't appear in rendered HTML code at all. Is it possible to either prevent ucSecond entirely from loading, or load it just once like ucFirst and keep it cached?

Related

Change one scriptlet display from a separate scriptlet

Fair warning: I don't understand half of what I know about this and I don't know that much so please forgive any terms misused or explanations unclear while I'm learning.
I am working on an ecommerce store application. It has an App_Themes with my theme and under that are Scriptlets - header, footer, content, sidebar, etc.
One of those is a Header with the store logo, etc.
Another is the content (of the receipt page in this case).
When a button is clicked on the receipt page I want to set the header scriptlet to go away. I was thinking a CSS display:none but can't figure out how to address that part in another scriptlet. I am not married to that idea either.
I can't directly address controls in a separate scriptlet, apparently.
Some code-ish examples.
Header:
!-- Store Banner-->
<div id="PageBanner">
<div id="PageBannerLogo">
[[ConLib:Custom/StoreLogo]]
</div>
</div>
[[ConLib:Custom/SwitchMobile]]
Content:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ReceiptPageInvoice.ascx.cs" Inherits="ConLib_Custom_ReceiptPage" %>
<%--
<conlib>
<summary>Display page to show details of an order like order items, shipping address, billing address etc.</summary>
<param name="AllowAddNote" default="true">If true, the customer can add notes to the order. If false, the customer can only see notes added by the merchant.</param>
<param name="HandleFailedPayments" default="false">If true, the customer is redirected to an order payment page if the payment fails at checkout.</param>
</conlib>
--%>
<script src="js/showHide.js"></script>
<%--Scrolls address bar out of the way on iphones.
<script type="application/x-javascript">
addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false);
function hideURLbar(){
window.scrollTo(0,1);
}
</script>--%>
<%# Register Src="~/ConLib/OrderTotalSummary.ascx" TagName="OrderTotalSummary" TagPrefix="uc" %>
<%# Register Src="~/ConLib/BreadCrumbs.ascx" TagName="BreadCrumbs" TagPrefix="uc" %>
<%# Register Src="~/ConLib/Custom/OrderItemDetail.ascx" TagName="OrderItemDetail"
TagPrefix="uc" %>
<%# Register Src="~/ConLib/Utility/PayPalPayNowButton.ascx" TagName="PayPalPayNowButton"
TagPrefix="uc" %>
<%-- this file is identical to ~/ConLib/MyOrderPage.ascx, with the addition of the affiliate tracker tag --%>
<%# Register Src="~/Checkout/AffiliateTracker.ascx" TagName="AffiliateTracker" TagPrefix="uc" %>
<asp:PlaceHolder runat="server" ID="ReceiptPagePh" Visible="True">
<asp:Panel runat="server" ID="InvoicePageTopPnl">
<asp:PlaceHolder ID="BalanceDuePanel" runat="server" Visible="false" EnableViewState="false">
<br/>
<asp:Label ID="BalanceDueMessage" runat="server" Text="** Your order has a balance of {0:lc} due.&nbsp <a href='{1}'><u>Pay Now</u></a>"
SkinID="ErrorCondition"></asp:Label>
<br/>
<br/>
</asp:PlaceHolder>
More of the Program....
The button I want to hide the header:
<asp:Button runat="server" ID="ShowTicketButton" OnClick="ShowTicketButton_Click" Text="Show Ticket" />
Skipping from one scriptlet to another is new to me. Within a single conlib is no problems but having a button in one change appearance of another is different. This is a level I've not reached.
Any help is much appreciated.
Jim
Wow, never saw no bites on SO. Probably because I was thinking about it ineffectively. My solution was to simply create a new layout scriptlet that had no header/footer and remove the breadcrumbs conlib from the content scriptlet. Now if we need a header I can just load it into the page and show and hide it at will. Thanks to all who looked at this... I know it's a weird one.

Changing ContentPlaceHolder's content dynamically

I have an index page as a content page and at the top of it i have a content place holder like this.
<asp:Content ID="Content3" ContentPlaceHolderID="logProcessHolder" runat="server">
<p class="header-link">login or create an account</p>
</asp:Content>
I want to change its content when users login. After login i want to put user name instead of these links. I have my login method already, just want to know how can i make this without using an another content page ? or is it a logical solution for me ? Should i use an another content page as a home page ?
I would wrap your options in asp:Panels or use the LoginView control as epaezr has done
<asp:Content ID="Content3" ContentPlaceHolderID="logProcessHolder" runat="server">
<asp:Panel ID="pnlAnonymous" runat="server">
<p class="header-link">login or create an account</p>
</asp:Panel>
<asp:Panel ID="pnlVerified" runat="server">
<asp:Literal ID="litUserName" runat="server" />
</asp:Panel>
</asp:Content>
Then in your code behind
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
pnlAnonymous.Visible = false;
pnlVerified.Visible = true;
litUserName.Text = Context.User.Identity.Name;
}
else
{
pnlAnonymous.Visible = true;
pnlVerified.Visible = false;
}
}
You don't have to use panels. You could also HTML elements and access them in the code-behind by giving them an ID and a runat="server" attribute. E.g: <p ID="loginLinks" runat="server" class="header-link">...etc...</p> where you could change the visibility with loginLinks.Visible
You can use the integrated login controls on your code, place them on the contentplaceholder and customize to show the users name...
So you place a asp:LoginView, and on its AnonymousTemplate you can place a asp:Login control and customize it, and on the LoggedInTemplate you can place the login name, a logout link, change password, etc.
Here's an example:
<asp:LoginView ID="LoginView1" runat="server">
<AnonymousTemplate>
<asp:Login ID="Login1" runat="server"></asp:Login>
</AnonymousTemplate>
<LoggedInTemplate>
<asp:LoginName ID="LoginName1" runat="server" /> | <asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="RedirectToLoginPage" LogoutText="End session" />
</LoggedInTemplate>
</asp:LoginView>
That code should be place right inside your ContentPlaceHolder
Hope this is useful!!
there are some ways around your question depends on your login method,
if your are using ASP.NET Forms Authentication then you could display your username just like below:
<%: Context.User.Identity.Name %>
and if you wanna have those links if user is not authenticated then you could have something like this inside your current content placeholder:
<asp:Content ID="Content3" ContentPlaceHolderID="logProcessHolder" runat="server"> > <p class="header-link">
<% if(Context.User.Identity.IsAuthenticated){ %>
<div><%: Context.User.Identity.Name %></div>
logout
<%} else { %>
login or
create an account
<%} %>
</p>
</asp:Content>
alternatively if you have your own method of authentication instead of Context.User.Identity.IsAuthenticated you could check your user's authentication from the database and pass it through a property from your code behind.

UserControl in asp .net is not working?

I have created a two usercontrols in asp.net and one webform . Now i want these two usercontrols to show in form in webform but it say that there must be one head with runat="server"
this is webform where i am using UserControl!
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Light.master" CodeBehind="AdministrationPage.aspx.cs" Inherits="DXApplication5.AdministrationPage" %>
<%# Register src="~/AdminPage/AssignmentTab.ascx" tagname="AssignmentUC" tagprefix="uc1" %>
<asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" runat="server">
<table border="0">
<tr>
<td>
<div class="accountHeader">
<uc1:AssignmentUC ID="CalendarUserControl1" runat="server" />
</div>
</td>
</tr>
</table>
</asp:Content>
This is UserControl below:
<%# Control Language="C#" ClassName="AssignmentUC" AutoEventWireup="true" CodeBehind="AssignmentTab.ascx.cs" Inherits="DXApplication5.AdminPage.AssignmentTab" %>
I would add a single form to your masterpage, this may be the cause of your error.
I would also remove all other form server controls from your user controls and pages.
Try these steps:
Go to Light.master master page file and make sure that this is in there somewhere <form id="form1" runat="server"> and a closing tag, the id may be different.
Go to the following files AssignmentTab.ascx and AdministrationPage.aspx and remove any <form id="form1" runat="server"> and closing tags </form>
Check user control code if it contains a head element. Also check all dependencies to see if there are head elements present in them.
I think you have use <form id="formID" runat="server"> in both of your page and user Control .
Just remove runat="server" from your user Control Form tag .
Make sure you have in your user control cs file:
public partial class WebUserControl1 : System.Web.UI.UserControl
In ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebUserControl1" %>
In aspx parent:
<%# Register Src="WebUserControl1.ascx" TagPrefix="uc" TagName="WebUserControl1 " %>
<uc:WebUserControl1 runat="server" ID="mycontrol" />

I am having an issue with ASP .NET user controls

I have an issue currently that I can't resolve. I have a user control called "Dashboard" which then has the following markup, containing several subcontrols.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="Dashboard.ascx.cs" Inherits="BlueSEQ.Controls.Dashboard.Dashboard" %>
<%# Register src="Administrator.ascx" tagname="Administrator" tagprefix="uc1" %>
<%# Register src="Provider.ascx" tagname="Provider" tagprefix="uc2" %>
<%# Register src="User.ascx" tagname="User" tagprefix="uc3" %>
<% if (isAdministrator)
{ %>
<uc1:Administrator ID="Administrator1" runat="server" />
<% }
else if (isProvider)
{ %>
<uc2:Provider ID="Provider1" runat="server" />
<% }
else
{ %>
<uc3:User ID="User1" runat="server" />
<% } %>
As you can see, I want it to display some controls or other controls depending on some conditions. However, all of these controls' "Load" event get triggered, even if they are not used.
How can I prevent this?
If you can help it, try to avoid having conditional logic in your markup. It could make the views somewhat more difficult to understand for designers (if you're working with designers) and more difficult to find and refactor this code in the future.
You should also take a look at ASP.NET MVC: Avoiding Tag Soup. Although it's ASP.NET MVC, it's still a good example of how adding logic to your views can quickly make them very difficult and unpleasant to maintain (initial example).
You could use the technique described here: How to: Add Controls to an ASP.NET Web Page Programmatically.
Your markup would look something like this.
<asp:PlaceHolder id="MyPlaceholder" />
and your codebehind would have something along the lines of
private void InitSection()
{
Control c;
if( isAdministrator )
c = Page.LoadControl("~\Administrator.ascx")
else if( isProvider )
c = Page.LoadControl("~\Provider.ascx")
else
c = Page.LoadControl("~\User.ascx");
MyPlaceholder.Controlls.Add(c);
}
The ideal way to do this is to set up asp.net role provider and use a LoginView control, something along the lines of the code below. LoginView only loads the appropriate content.
<asp:LoginView runat="server">
<AnonymousTemplate>
<uc1:User ID="User" runat="server" />
</AnonymousTemplate>
<RoleGroups>
<asp:RoleGroup Roles="Administrator">
<ContentTemplate>
<uc1:Administrator ID="Administrator1" runat="server" />
</ContentTemplate>
</asp:RoleGroup>
<asp:RoleGroup Roles="Provider">
<ContentTemplate>
<uc1:Provider ID="Provider" runat="server" />
</ContentTemplate>
</asp:RoleGroup>
</RoleGroups>
</asp:LoginView>
You have to Load the control on a specific condition instead, so try to set visible/invisible with the usercontrol, that's a much better approach
<% if (isAdministrator)
{ %>
Page.LoadControl(("~\Administrator1.ascx");
<% }
How about using a MultiView control?
MultiView on MSDN

How to load menu only once time in Master Page?

I created Master page which has got mainNavigator panel on top of page that is a web user control(BuildMenu.ascx). I am filling UC Menu in master page's loading :
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="IntermMaster.master.cs" Inherits="MyProject.IntermMaster" EnableViewState="true" %>
<%# Register src="Utils/BuildMenu.ascx" tagname="BuildMenu" tagprefix="uc1" %>
>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<uc1:BuildMenu ID="BuildMenu2" runat="server" />
</div>
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
This is loading in postback event:
BuildMenu.ascx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Fill Menu from DataBase (Compare SiteMap...)
}
Every post back BuildManu.ascx is loading every time tihs is really bored me. How can i solve it. I want to do only one time load BuildMenu.ascx (in master page)
Unless you want to use frames (and you probably do not), the control has to be reloaded each time so it can be rendered. The best you can do is to use server-side output caching so that it takes less processing time to load the control.
To do output caching, put this in your page:
<%# OutputCache Duration="[Number of Seconds]" VaryByParam="None" %>
The load method WILL be called every time a postback occures (except for AJAX pages, but let's not go there). Take a look at the ASP.NET page lifecycle.
What you can do is just return from the controls Load event if the value of IsPostBack is true.
However, if the control in question is static (or almost static) in content you could try using output cashing on the server, that way the control will be loaded once in a while, and the rest of the times, the server will just use it's cashed copy.
i have a better idea why dont you sue a session it will help you
make like this ::
protected void Page_Load(object sender, EventArgs e)
{
if session(ispostback") <> "menuloaded"
{
// Fill Menu from DataBase (Compare SiteMap...)
Session("ispostback")="menuloaded"
}
this will work for sure

Categories

Resources