Clear Output Cache from User Control in Asp.Net - c#

i have a user control with a name uc_Menu.ascx. The menues are loaded dynamically Role base. So, i inlude it in a user control and cached it like this;
Note: for testing purpose i have just provide 60 sec cache;
<%# OutputCache Duration="60" VaryByParam="none" %>
<td id="Menu">
<div id="firstpane" runat="server" class="menu_list">
<p class="menu_head">
<a href="/forms/Dashboard.aspx">
<span style="background: url('/App_Themes/Default/Images/icons/ic_grid.png') no-repeat"></span>
DashBoard
</a>
</p>
</div>
</td>
The code behind looks like this;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BulitMenus();
Response.Write("<h1>" + DateTime.Now.ToString() + "</h1>");
}
}
My master page where i have referenced the above user control;
<%# Register Src="~/UserControls/uc_Menu.ascx" TagPrefix="Ken" TagName="Menu" %>
<Ken:Menu runat="server" id="Menus" />
Now, when i tested this, it works fine (when page is loaded for the first time, cache worked)
However, I want to clear the cache when a user click on LogOff button (on a master page) because the menus are role base and an admin might give more permissions to user. In that case it is necessary to relode the menus again.
So, How do i clear the cache from a user control;
Note: I have also tried this but it deosn't work;
http://aspalliance.com/668_Remove_ASPNET_Page_Output_Cache_Entries
AND
protected void Lbtn_LogOff_Click(object sender, EventArgs e)
{
HttpResponse.RemoveOutputCacheItem("/UserControls/uc_Menu.ascx");
// this code is copied from a url above which i have included i my question
HttpContext.Current.Cache.Insert("Pages", DateTime.Now, null,
System.DateTime.MaxValue, System.TimeSpan.Zero,
System.Web.Caching.CacheItemPriority.NotRemovable, null);
FormsAuthentication.SignOut();
Response.Redirect("~/authorization/Login.aspx");
}

Related

How to set a paragraph text dynamically in ASP.NET?

I am creating a website in asp.net. My website has an admin page. The admin will use this page to daily update website's content. This content will get reflected to the main website. I have learned from the following link that how we can pass values from one page to another-
How to pass values across the pages in ASP.net without using Session
I am using Application variable.
Admin.aspx
<form runat="server">
<div>
<asp:TextBox id="DailyMsgID" name = "DailyMsgName" runat="server"></asp:TextBox>
<asp:Button id="b1" Text="Submit" runat="server" OnClick="b1_Click" />
<asp:Label ID="Label_DailyMsgId" name="Label_DailyMsgName" runat="server" Text="Label"></asp:Label>
</div>
</form>
</body>
Admin.aspx.cs
protected void b1_Click(object sender, EventArgs e)
{
Label_DailyMsgId.Text = DailyMsgID.Text;
Application["DailyMessage"] = Label_DailyMsgId.Text;
}
Home.aspx
<!-- Page content-->
<div id="div1" class="container-fluid">
<h1 id="myhead" class="mt-4">Welcome to the Official Website of ABC</h1>
<p id="DailyMessage"></p>
</div>
To set the paragraph, I want to do something like below. But it is not recognising the paragraph Id.
Home.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
DailyMessage.Text = Application["DailyMessage"].ToString();
}
How do I set the paragraph?
Both Admin and Home page are under the same solution.
This issue got resolved. I was missing
runat="server"
Here is the updated code -
Home.aspx
<p id="DailyMessage" runat="server"></p>
Home.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
DailyMessage.InnerText = Application["DailyMessage"].ToString();
}

How to make user control load once?

I have one user control,named as "SocialShareElements", which's purpose is to share the page content/image into FaceBook.
I utilized this user control in my Index page.
I called this user control in a "IF" condition, within Index.aspx.
The pseudo code is like:
<%
if (Request.IsSecureConnection)
{
%>
<div class="deal-detail-head tzsg-margin-bottom-med">
<MyControl:SocialShareElements ID="SocialShareElements1" runat="server"/>
</div>
<div class="clear-both"></div>
<%
}
else
{
%>
<div class="deal-test bottom-small">
<MyControl:SocialShareElements ID="SocialShareElements" runat="server"/>
</div>
<%
}
%>
When I test the FBShare function in https://developers.facebook.com/tools/debug/og/object/, it showed failed becuase I loaded "SocialShareElements" twice, and this makes meta data of "SocialShareElements" double in Index.aspx.
My question is how to adjust the logic of utilizing "SocialShareElements" in Index.aspx, to make it only be loaded once.
Thank you.
You can achieve this from code-behind.
Modify your div on your aspx page to be available from server side:
<div id="socialShare" runat="server">
</div>
In your code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if(Request.IsSecureConnection)
{
SocialShareElements shareElement = LoadControl("SocialShareElements.ascx") as SocialShareElements;
socialDiv.Controls.Add(shareElement);
}
}

OnClick not firing in UserControl when button is clicked

I have a master page. In the master page I have a UserControl for the footer. In the footer I have a button that is not firing OnClick. During debugging I see the function being called by OnClick, btnSignup_Click, is not getting hit. I can't seem to figure out where the mistake in my code is.
Also I wanted to note that the validation functionality is working correctly.
master.master
<%# Master Language="C#" AutoEventWireup="true" Inherits="master" Codebehind="master.master.cs" %>
<%# Register TagPrefix="xyz" TagName="Footer" Src="~/controls/footer.ascx" %>
<xyz:Footer ID="Footer" runat="server" />
footer.ascx
<%# Control Language="C#" AutoEventWireup="true" Inherits="footer" Codebehind="footer.ascx.cs" %>
<div>
<asp:TextBox ID="fName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorfName" ValidationGroup="validationSignup" Display="Static" ControlToValidate="fName" ErrorMessage="First Name required" runat="server"></asp:RequiredFieldValidator>
</div>
<div class="button">
<asp:Button ID="btnSignup" CommandName="Button" runat="server" ValidationGroup="validationSignup" Text="Signup" HeaderText="Please fill in all required fields before continuing." OnClick="btnSignup_Click"/>
</div>
<div class="validationSummary">
<asp:ValidationSummary ID="ValidationSummary" ValidationGroup="validationSignup" runat="server"></asp:ValidationSummary>
</div>
footer.ascx.cs
public partial class templates_site_footer : BaseUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
btnSignup.Click += new EventHandler(btnSignup_Click);
}
protected void btnSignup_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
return;
// code to execute after button is clicked
}
}
Remove btnSignup.Click += new EventHandler(btnSignup_Click); code from Page_Load event, You had already assigned OnClick event to button in .ASCX markup and no need to check validate of your page again in btnSignup_Click, you can directly write button click event code which you want to execute.
Your Footer User Control Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
//btnSignup.Click += new EventHandler(btnSignup_Click);
}
protected void btnSignup_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
// code to execute after button is clicked
}
else
{
// Your page does not validated.
}
}

Retrieving ascx control value from a callback registered on master page. Control added to Repeater's PlaceHolder during OnItemCreated

This is my best attempt to simplify the code to ask the question well. Hopefully it helps.
The short: I need to get the value of a dynamically created Control whose path is loaded from the database and added to a Repeater that contains a PlaceHolder. The value needs to be retrieved from a function on the child page that is called from the master page.
The long:
I have a master page that has a lot of settings on it, and an area where a child page can add its own configuration options. Let's say the master page is as follows:
<%# Master Language="C#" MasterPageFile="~/MainTemplate.master" CodeBehind="ConfigureChoices.master.cs" Inherits="Demo.ConfigureChoices"
AutoEventWireup="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="RenderArea" runat="Server">
<asp:Panel runat="server" ID="PanelConfiguration">
<asp:TextBox ID="TextBoxForSomething" runat="Server"/>
<asp:DropDownList ID="AnotherConfigurableThing" runat="server" OnSelectedIndexChanged="DropDownConfiguration_Click" AutoPostBack="true">
<asp:ListItem Text="Option 1" Selected="True" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
<asp:ListItem Text="Option 3" Value="3"></asp:ListItem>
</asp:DropDownList>
<!--etc-->
<asp:ContentPlaceHolder ID="CustomSettings" runat="server">
</asp:ContentPlaceHolder>
<asp:Button ID="ButtonSubmit" runat="Server" Text="Submit" OnClick="ButtonSubmit_Click" />
</asp:Panel>
</asp:Content>
In codebehind, I need to persist the settings to the database, including custom settings from the user page. The child pages need some of the data created from the master page in order to persist its data. To accomplish this, I have an event that gets populated on child page load and called prior to redirect. It looks like this:
public delegate void BeforeSubmitEventHandler(int configInfoID);
public event BeforeSubmitEventHandler BeforeSubmit;
protected void ButtonSubmit_Click(object sender, EventArgs e)
{
ConfigInfo config = new ConfigInfo;
config.EnteredText = TextBoxForSomething.Text;
config.SelectedValue = AnotherConfigurableThing.SelectedValue;
int configID = AddToDatabase(config);
if (BeforeSubmit != null)
BeforeSubmit(configID);
Response.Redirect("RedirectURL.aspx");
}
The custom section of the user page has a Repeater, a DropDownList, and an "Add" Button. The Repeater has the name of the option, a short description, a delete image, and a PlaceHolder for loading custom controls from the database. More on that after the code:
<%# Page Title="" Language="C#" MasterPageFile="~/ConfigureChoices.master" ValidateRequest="false"
AutoEventWireup="true" Inherits="Demo.CustomChoicePage1" Codebehind="CustomChoicePage1.aspx.cs"
MaintainScrollPositionOnPostback="true" %>
<asp:Content ID="MyContent" ContentPlaceHolderID="CustomSettings" runat="server">
<asp:Repeater ID="RepeaterSelectedOptions" OnItemCreated="OnOptionAdded" runat="server">
<HeaderTemplate>
<table id="SelectedOptionsTable">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# Server.HtmlEncode(Eval("Name").ToString()) %>
</td>
<td>
<%# Server.HtmlEncode(Eval("Description").ToString()) %>
</td>
<td>
<asp:ImageButton ImageUrl="delete.png" ID="ImgDeleteOption" runat="server" OnCommand="DeleteOption_Click"
CommandArgument='<%# Eval("OptionID") %>' />
</td>
</tr>
<asp:PlaceHolder runat="server" ID="optionConfiguration" />
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
<br />
<asp:DropDownList ID="DropDownListAvailableOptions" runat="server" />
<asp:Button ID="ButtonAddOption" runat="server" Text="Add Option" OnCommand="AddOption_Click" />
</asp:Content>
In codebehind, the Repeater is populated the first time on Page_Load using the following code (combination of C# and pseudocode to shorten this already-long question):
protected void Page_Load(object sender, EventArgs e)
{
((ConfigureChoices)Master).BeforeSubmit += OnSubmit;
if (!Page.IsPostBack)
{
RefreshOptions();
}
}
protected void RefreshOptions()
{
List<Option> fullList = GetOptionsFromDB();
List<Option> availableList = new List<Option>();
List<Option> selectedList = new List<Option>();
List<int> selectedOptions = GetSelectedOptions();
// Logic here to set the available/selected Lists
DropDownListAvailableOptions.DataSource = availableList;
DropDownListAvailableOptions.DataBind();
RepeaterSelectedOptions.DataSource = selectedList;
RepeaterSelectedOptions.DataBind();
}
public List<short> GetSelectedOptions()
{
List<int> selectedOptions = this.ViewState["SelectedOptions"];
if (selectedOptions == null)
{
selectedOptions = new List<int>();
foreach (Option option in GetOptionsFromDB())
{
selectedOptions.Add(option.OptionID);
}
}
return selectedOptions;
}
If the add or remove buttons are clicked, the following methods are used:
public void AddOption_Click(object sender, CommandEventArgs e)
{
List<int> selectedOptions = GetSelectedOptions();
selectedOptions.Add(Convert.ToInt32(DropDownListAvailableOptions.SelectedValue));
this.ViewState["SelectedOptions"] = selectedTests;
RefreshOptions();
}
public void DeleteOption_Click(object sender, CommandEventArgs e)
{
List<int> selectedOptions = GetSelectedOptions();
selectedOptions.Remove(Convert.ToInt32(e.CommandArgument));
this.ViewState["SelectedOptions"] = selectedOptions;
RefreshOptions();
}
Finally, the meat of where I think the issue might be, and some explanation of what I've tried. When an option is added to the control, a different table is queried to see if there's an additional ascx that must be loaded into the placeholder. This happens in the method pointed to by OnItemCreated in the Repeater:
protected void OnOptionAdded(Object sender, RepeaterItemEventArgs e)
{
if (e.Item == null || e.Item.DataItem == null)
return;
short optionID = ((Option)e.Item.DataItem).OptionID;
OptionControl optionControl = GetControlForOptionFromDB(optionID);
if (optionControl == null)
return;
CustomOptionControl control = (CustomOptionControl)this.LoadControl(optionControl.Path);
control.ID = "CustomControl" + optionID.ToString();
TableRow tableRow = new TableRow();
tableRow.ID = "CustomControlTR" + optionID.ToString();
tableRow.CssClass = "TestConfiguration";
TableCell tableCell = new TableCell();
tableCell.ID = "CustomControlTC" + optionID.ToString();
tableCell.ColumnSpan = 3;
e.Item.FindControl("optionConfiguration").Controls.Add(tableRow);
tableRow.Cells.Add(tableCell);
tableCell.Controls.Add(control);
}
So all of the above "works" in that I see the control on the page, the lists work correctly, and stuff like that. When I click the "Submit" button, I see the configuration (for the sake of this example, let's just say it's a single checkbox) in the Request form variable. However, setting a breakpoint in my callback method on the child page, the CustomOptionControl does not appear to be in the RepeaterSelectedOptions. Only the Option is present.
I have tried at least the following, and more (but I honestly can't recall every step I've tried):
adding a call to RefreshOptions to an overridden LoadViewState
after the call to load the base
doing my initial Repeater binding
in Page_Init instead of Page_Load
different orders of adding the table row, cell, and custom controls to each other and the main
page
How should I be structuring this page and its necessary databinding events so that I can make something like the commented lines in the following code work? When I break at the start of the method and look through the RepeaterOptions.Controls, the CustomOptionControls are gone.
protected void OnSubmit(int configID)
{
//List<CustomOptionControl> optionsToInsert = find CustomOptionControls in RepeaterOptions (probably an iterative search through the Controls);
//foreach (CustomOptionControl control in optionsToInsert)
//{
// control.AddOptionToDatabase(configID);
//}
}
I'm not sure what changed, maybe it was taking the break to rubber duck debug using all of the above. I've gone back and tried tweaking some of the things I had before (order of insertion, which call to use, etc) to see if they make a difference, but either way, the Control is now being persisted in the ViewState properly with the above code. It is available on postback from the master page call so long as the following is added (bullet #1 of what I tried before):
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
RefreshOptions();
}
Earlier, savedState was only showing the List<int> added to it to maintain selected options. At some point in tweaking and debugging, I saw that the controls I created were now in the viewstate, and adding a RefreshOptions call worked. This means on postback for add/remove there are two calls to RefreshOptions, but I can either work around that or ignore it, since behavior is still correct. Thanks for looking!

Manipulating a control in a child from the parent page

The answer is probably obvious but I have not seen anything I could use except the opposite - manipulating the parent from the child - so I'm posting new.
I have a shopping cart system I'm working on that my company purchased and I'm new to .NET so I may not even ask this properly.
My store has a page in the checkout portion that looks basically like this:
PaymentPage.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="PaymentPage.ascx.cs" Inherits="ConLib_PaymentPage" %>
<%# Register Assembly="CommerceBuilder.Web" Namespace="CommerceBuilder.Web.UI.WebControls" TagPrefix="cb" %>
<%# Register Src="~/Checkout/PaymentForms/CreditCardPaymentForm.ascx" TagName="CreditCardPaymentForm" TagPrefix="uc" %>
<ajax:UpdatePanel ID="PaymentAjax" runat="server">
<ContentTemplate>
On page controls, etc.
Then a checkbox saying they've read the terms and agree:
<div id="terms">
<asp:CheckBox ID="AgreeTerms" runat="server" Text="I agree to the Terms Of Service" CssClass="Terms" AutoPostBack="True" OnCheckedChanged="AgreeTerms_Clicked"/>
</div>
The task I want to accomplish is in the OnCheckedChanged event I want to enable or disable an imagebutton inside the CreditCardPaymentForm control.
That code looks like this:
<%# Control Language="C#" ClassName="CreditCardPaymentForm" EnableViewState="false" %>
<%# Register Assembly="CommerceBuilder.Web" Namespace="CommerceBuilder.Web.UI.WebControls" TagPrefix="cb" %>
<%# Register assembly="wwhoverpanel" Namespace="Westwind.Web.Controls" TagPrefix="wwh" %>
... a <script> block with some code and then HTML
<span class="TTAActionButton">
<br>
<asp:ImageButton ID="CreditCardButton" runat="server" ToolTip="Pay With Card" SkinID="TTAPlaceOrder" OnClick="CreditCardButton_Click" />
<asp:HiddenField runat="server" ID="FormIsSubmitted" value="0" />
<br /><br /><br />
</span>
I want to be able to turn the CreditCardButton on and off depending on whether the checkbox is checked. I would have a routine in the page codebehind like:
public void AgreeTerms_Clicked(object sender, EventArgs e)
{
if (AgreeTerms.Checked)
CreditCardButton.Enabled = false;
}
but every permutation of that I try has failed.
I have abbreviated the code but if I've left out too much please let me know.
Thanks for your help and if you assume I know nothing about .NET then double-thanks!
Jim
In the CreditCardPaymentForm control create a property that exposes the CreditCardButton visibility and than use that from the parent in the OnCheckedChanged function handler.
public bool ShowCreditCardButton
{
get { return CreditCardButton.Visable; }
set { CreditCardButton.Visable = value; }
}
Does CreditCardPaymentForm include a PaymentPage.ascx? That is, does the form 'use' the PaymentPage user control?
if so, your best bet it is to publish an event on PaymentPage that is raised by the checking of the checkbox:
public void AgreeTerms_Clicked(object sender, EventArgs e)
{
if (AgreeTerms.Checked)
OnTermsAgreed();
}
private void OnTermsAgreed()
{
// raise TermsAgreed event
var evt = TermsAgreed;
if (null != evt)
evt(this, EventArgs.Empty);
}
public event EventHandler TermsAgreed;
Then CreditCardPaymentForm subscribes to that event and 'does its thing' which in your case is to enable the button it knows about.

Categories