ASP.NET randomly caching output - asp.net

I created a basic asp.net page, with a GridView and simple controls for search and paging purposes. If I click on the "next page" button, sometimes the output is exactly the same than the previous postback, sometimes is the correct output.
This behavior was found using regular and ajax postbacks. And I have used Fiddler and confirmed that is not the browser caching the output.
And I am not using any outputcache directive.
Example:
open page, click "next", it's still page 1. click "next" again, now it's page 3.
It is completely random, sometimes it works fine, sometimes don't. Does anyone know what could be causing this behavior?
ASPX Page:
<asp:Panel ID="PanelSearch" runat="server" GroupingText="Search Result" HorizontalAlign="Left"
Width="100%" Style="clear: both">
<uc1:dashboard_search ID="Dashboard_search1" runat="server" OnOnNeedSubs="Dashboard_search1_OnNeedSubs" /><br />
<asp:Button ID="btnBack" runat="server" Text="Previous page" Visible="false"
onclick="btnBack_Click" />
<asp:Label ID="lblPageNumber" runat="server"></asp:Label>
<asp:Button ID="btnNext"
runat="server" Text="Next Page" Visible="false"
onclick="btnNext_Click"/>
<asp:HiddenField ID="hidPageNumber" runat="server" Value="0" />
</asp:Panel>
This code is inside an UpdatePanel (but without an UpdatePanel it still occurs the same thing).
This is the code behind code:
public void Dashboard_search1_OnNeedSubs(object sender, SubSSDEventArgs e)
{
e.SubSSDs = doSearch();
}
protected List<SubSSD> doSearch()
{
// [filter code]
int total = SubSSD.getTotalNumber();
int page = Convert.ToInt32(hidPageNumber.Value);
if (page == 0)
btnBack.Visible = false;
else
btnBack.Visible = true;
if (page + 26 >= total)
btnNext.Visible = false;
else
btnNext.Visible = true;
lblPageNumber.Text = "Page " + Convert.ToInt32((page / 25) + 1) + "/" + Convert.ToInt32((total / 25) + 1);
List<SubSSD> subssds = SubSSD.search(page, page + 26);
return subssds;
}
protected void btnBack_Click(object sender, EventArgs e)
{
int page = Convert.ToInt32(hidPageNumber.Value);
hidPageNumber.Value = Convert.ToString(page - 25);
}
protected void btnNext_Click(object sender, EventArgs e)
{
int page = Convert.ToInt32(hidPageNumber.Value);
hidPageNumber.Value = Convert.ToString(page + 25);
}

To completely eliminate the browser side, I would attach a random url parameter. I'll note that most of the major javascript libraries do this transparently with their ajax features.

Sounds to me like you should either put some logging in place or a lot of breakpoints to identify exactly which methods are being called in which order.
I suspect that the grid binding is happening out of order of your next page code.

Guys, i found out why it was having such strange behavior, there was a OutputCache directive in the user control, for caching the content for 5 seconds.

Related

Viewstate expires after some time for application page in SharePoint 2013?

I have a simple ASP application page added in a SharePoint project just for presentation purposes, so it's ASP web forms page is hosted in SharePoint.
HTML:
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<asp:Label runat="server">Number 1:</asp:Label>
<asp:TextBox ID="num1" runat="server"></asp:TextBox>
<asp:Label runat="server">Number 2:</asp:Label>
<asp:TextBox ID="num2" runat="server"></asp:TextBox>
<asp:Label runat="server">Result:</asp:Label>
<asp:TextBox ID="res" runat="server"></asp:TextBox>
<asp:Button Text="ADD Numbers" runat="server" OnClick="Unnamed_Click" />
<asp:ListBox runat="server" ID="list" />
<asp:Label runat="server" ID="previousListValue"></asp:Label>
<asp:Label runat="server">Exception:</asp:Label>
<asp:TextBox ID="exception" runat="server"></asp:TextBox>
</asp:Content>
Here is code behind:
public partial class Default : LayoutsPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
list.DataSource = new List<ListItem>() {
new ListItem("value1", "1"),
new ListItem("value2", "2"),
new ListItem("value3", "3"),
};
list.DataBind();
}
}
protected void Unnamed_Click(object sender, EventArgs e)
{
try
{
res.Text = Convert.ToString(int.Parse(num1.Text) + int.Parse(num2.Text));
previousListValue.Text = "Previous list selected value is: " + list.SelectedItem.Value;
exception.Text = string.Empty;
}
catch (Exception ex)
{
exception.Text = ex.GetType().ToString() + "\t" + ex.Message;
}
}
}
When you click "ADD Numbers" button and addition of num1 and num2 textboxes is appended to the res textbox and selected value of ListBox is shown in label next to it. This works flawlessly if correct values are entered for a number and an item is selected in ListBox.
If the page is left (not interacted with) for about 10-15 minutes and "ADD Numbers" button is clicked, NullReferenceException will be thrown for list.SelectedItem.Value and also textBoxes will be empty. What happened is that the application is in postBack state(Page.IsPostBack is true) but viewstate is not restored.
I guess this has something to do with ViewState being moved to distributed cache as of version 2013 but can someone clarify this for me, and suggest me the most effective way to go about this, without changing AppFabric configuration, because 10-15 minutes of ViewState perversion is not acceptable.
As the ViewState is saved in the user's session, it is possible for
ViewState to expire if a page is not posted back within the session
expiration time.
You can configure your session timeout in web.config file (Session timeout in ASP.NET):
<sessionState timeout="60" />
(Where 50 and 60 are minutes)
You can also check if your session expired using this sample code in Master Page's Page_Load method:
if (Session.Contents.Count == 0)
{
//Session dead!
}
else
{
//Session alive!
}
Or save the logged user and test if it's null:
if (Session["userId"] == null)
{
//Session dead!
}
else
{
//Session alive!
}

Disable Button after click in dnn

for one requirements i need to disable button after click and run server side code after disabled for this i have used below code which is called at pageload
btnGREntry.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(btnGREntry, "") +
";this.value='Please wait...';this.disabled = true;");
but it is giving me below error.
An unknown error occurred while processing the request on the server.
The status code returned from the server was: 0
please help me to find out a solution or suggest any other solution to disable button after click
Note: similar things are working in asp.net but i am using in *dotnetnuke version 7.0 *
You can do this in the code-behind.
ASPX
<asp:Button ID="Button1" runat="server" onclick="Button1_Click1" Text="Button" />
Code-behind
protected void Button1_Click1(object sender, EventArgs e)
{
Button a = (Button)sender;
a.Enabled = false;
}
Does the button have to remain disabled continuously or is it to return to enabled after page refresh? In the former case then handle it with both JavaScript and code behind. In the later case handle it with just JavaScript.
<asp:Button ID="Button1" runat="server" onClientClick="DisableButton();" onclick="Button1_Click1" Text="Button" />
JavaScript:
function DisableButton() {
var btn = $("#buttonID").attr("disabled", "disabled");
}

How to avoid Page_Load() on button click?

I have two buttons, preview and Save. With help of preview button user can view the data based on the format and then can save.
But when preview is clicked, one textbox attached to ajaxcontrol (Calender) becomes empty and user have to fill the date before saving. How to handle this? On preview click i get the details to show the data in layout.
<asp:TextBox ID="txtDate" ReadOnly="true" runat="server"></asp:TextBox>
<div style="float: right;">
<asp:ImageButton ID="imgcalender1" runat="server" ImageUrl="~/images/calendar.png"
ImageAlign="Bottom" />
<asp:CalendarExtender ID="ajCal" TargetControlID="txtpublishDate" PopupButtonID="imgcalender1"
runat="server">
</asp:CalendarExtender>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ValidationGroup="group1" runat="server" ControlToValidate="txtDate"
ForeColor="Red" Font-Bold="true" ErrorMessage="*"></asp:RequiredFieldValidator>
</div>
<asp:Button ID="btnPreview" runat="server" Text="Preview" OnClick="btnPreview_Click" />
<asp:Button ID="btnsubmit" runat="server" ValidationGroup="group1" Text="Save" OnClick="btnsubmit_Click" />
Use Page.IsPostback() in your aspx code (server-side). Like this:
private void Page_Load()
{
if (!IsPostBack)
{
// the code that only needs to run once goes here
}
}
This code will only run the first time the page is loaded and avoids stepping on user-entered changes to the form.
From what I am understanding the preview button is causing a postback and you do not want that, try this on your preview button:
<asp:button runat="server".... OnClientClick="return false;" />
similarly this also works:
YourButton.Attributes.Add("onclick", return false");
Edit:
it seems the answer to the user's question was simple change in the HTML mark up of the preview button
CausesValidation="False"
you can put your code in
Page_Init()
{
//put your code here
}
instead of
Page_Load()
{
//code
}
I had the same problem and the solution above of "CausesValidation="False"" and even adding "UseSubmitBehavior="False"" DID NOT work - it still called "Page_Load" method.
What worked for me was adding the following line up front in Page_Load method.
if (IsPostBack) return;
I am mentioning this if it helps someone (I meant to comment above but StackOverflow did not allow me to comment because I am a new user - hence a new reply).
Try adding this to the buttons properties in the aspx page.
OnClientClick="return false;"
For my the #tgolisch answer worked better, maybe it's because i'm still a rookie.
I was trying to load a simple captcha in my WebForm and end up using a Reference Type in the Page_Load event and in a Button Click event (for a code snippet).
In the end i only have to edit some things and it's done:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var captchaText = generateCaptchaCode(5);
lblCaptcha.Text = captchaText;
}
}
protected void btnCheckCaptcha_Click(object sender, EventArgs e)
{
if (txtCaptchaCode.Text == lblCaptcha.Text)
lblMessage.Text = "Right input characters";
else
lblMessage.Text = "Error wrong characters";
}
form1.Action = Request.RawUrl;
Write this code on page load then page is not post back on button click

How do I load two ASP.NET UserControls on Demand?

I want load two user controls on demand.
asp:UpdatePanel ID="UpdatePanel1" runat="server"
ContentTemplate
asp:Button ID="Button1" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button1_Click" /
div id='Div_UserControlPlace' enableviewstate="true" runat="server"
/div
/ContentTemplate
Triggers
asp:PostBackTrigger ControlID="Button1" /
/Triggers
/asp:UpdatePanel
asp:UpdatePanel ID="UpdatePanel2" runat="server"
ContentTemplate
asp:Button ID="Button2" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button2_Click" /
div id='Div_UserControlPlace2' enableviewstate="true" runat="server"
/div
/ContentTemplate
aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl = new Control();
FeaturedProductUserControl = LoadControl("WebUserControl1.ascx");
FeaturedProductUserControl.EnableViewState = true;
Div_UserControlPlace.Controls.Add(FeaturedProductUserControl);
}
protected void Button2_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl2 = new Control();
FeaturedProductUserControl2 = LoadControl("WebUserControl2.ascx");
FeaturedProductUserControl2.EnableViewState = true;
Div_UserControlPlace2.Controls.Add(FeaturedProductUserControl2);
}
I load the first user control by clicking on the first button - this works properly but when I click on the other button to load the second UserControl, the first UserControl disappears and the second UserControl loads.
Thanks
IFA_User
You should use the Placeholder control to dynamically add your controls to the form.
Take a look at my last responses about dynamic controls:
OnClick event of dynamically created LinkButtons is not working
Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
Dynamically create an ImageButton
Now I already have some code working for demo purpose, each dynamic user controls keeps its state across post backs
This is the output:
ASPX
<asp:PlaceHolder runat="server" ID="addresses" /><br />
<asp:Button Text="Add Address" runat="server" ID="addAddress" OnClick="addAddress_Click" />
ASPX Code behind
protected void Page_PreLoad(object sender, EventArgs e)
{
for (int i = 0; i < this.DynamicControlsCount; i++)
{
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
}
protected void addAddress_Click(object sender, EventArgs e)
{
this.DynamicControlsCount++;
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
protected int DynamicControlsCount
{
get
{
if (this.ViewState["ac"] == null)
{
return 0;
}
return (int)this.ViewState["ac"];
}
set
{
this.ViewState["ac"] = value;
}
}
ASCX
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddressControl.ascx.cs" Inherits="WebApplication1.AddressControl" %>
<asp:Panel ID="Panel1" runat="server" GroupingText="Address" DefaultButton="btnSave">
Street: <asp:TextBox runat="server" ID="txtStreet" /><br />
City: <asp:TextBox runat="server" ID="txtCity" /><br />
<asp:Button Text="Save" runat="server" ID="btnSave" OnClick="btnSave_Click" />
</asp:Panel>
<asp:Panel runat="server" GroupingText="Address Summary" Visible="false" ID="summary">
<asp:Label ID="lblStreet" runat="server" /><br />
<asp:Label ID="lblCity" runat="server" />
</asp:Panel>
ASCX Code behind
protected void btnSave_Click(object sender, EventArgs e)
{
this.summary.Visible = true;
this.lblCity.Text = "Selected city: " + this.txtCity.Text;
this.lblStreet.Text = "Selected street: " + this.txtStreet.Text;
}
When a user control is created in the HTML, asp.net will persist across postbacks without any user interaction. But if you are loading them programatically (dynamically), they will not persist accross postbacks. So if you load them programmatically, you have the added task of persisting them programmatically as well. Use the ViewState (or Session I suppose) to store what has been loaded and perhaps any other necessary information that needs to be loaded between postbacks. Every single postback will require you to reload every control or else they will disappear.
There are couple of ways of doing it:
U can load the UserControls using Ajax. Benefit of using Ajax, is ur page does not get post back, thus for example, on click event of Button1, call a ajax(traditional/Jquery) to load UserControl1, and on button click of Button2 User control2.
Put the two button in two different updated panel, by doing this the click event will only refresh a part of ur page.
U have to save somewhere (ViewState/Session),which buttons are clicked, and upon clicking of any button check the value of that variable, and explicit load the control.
Points to note - If u want to get ur data back when ur page made a complete postback, then u have to add the controls keeping in mind the Page load event cycle.

set linkbutton as default button for asp:panel in asp.net [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Link Button on the page and set it as default button, work fine in IE but not in Mozila
How to set linkbutton as default button for asp:panel in asp.net? I know a button can be set as default but my application uses linkbuttons for all forms. Any suggestion how it can be done.
EDIT:
Now i tried this,
It works in firefox as well but my javascript validation (ie) onclient click of my linkbutton doesn't work why?
var __defaultFired = false;
function WebForm_FireDefaultButton(event, target) {
var element = event.target || event.srcElement;
if (!__defaultFired && event.keyCode == 13 && !(element && (element.tagName.toLowerCase() == "textarea"))) {
var defaultButton;
if (__nonMSDOMBrowser)
defaultButton = document.getElementById(target);
else
defaultButton = document.all[target];
if (defaultButton) {
if (typeof (defaultButton.click) != "undefined")
defaultButton.click();
else
eval(unescape(defaultButton.href.replace("javascript:", "")));
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
}
}
return true;
}
Second EDIT:
I was able make my custom linkbutton control work but couldn't able to hook OnClientClick to it. Source using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net.
and i did this,
<%# Register Namespace="App_Code" TagPrefix="ac" %>
<asp:Label runat="server" ID="lblHello" />
<asp:Panel runat="server" DefaultButton="lbHello">
First name: <asp:TextBox runat="server" ID="txtFirstName" />
<ac:LinkButtonDefault ID="lbHello" runat="server" Text="Click me"
OnClientClick="javascript:alert('hai');" OnClick="lbHello_Click" />
</asp:Panel>
My Clientside function doesn't work why? Any suggestion.
Rather than use a custom control you could take the simple approach of adding an attribute to handle the textbox's onKeyPress event. This correctly handles pressing Enter from the textbox and triggering the LinkButton's event. The downside to this approach is that any LinkButton OnClientClick event will not be triggered in Firefox, which is related to the issue described in that blog post you linked to. It will only be triggered when the user actually clicks on the link with their mouse. However, in IE, it will trigger from both the textbox and from being clicked on directly.
Solution #1 - The code to add the attribute is as follows:
protected void Page_Load(object sender, EventArgs e)
{
txtFirstName.Attributes.Add("onKeyPress",
"javascript:if (event.keyCode == 13) __doPostBack('" + lbHello.ClientID + "','')");
}
Try that and see if it fits your needs. Just bear in mind the limitation I described earlier.
Now, if you want the above limitation to go away, one of the comments from that blog post showed an approach that appears to work correctly. I've modified it to get rid of the StringBuilder and converted it to C#.
Solution #2 - The code to add the function and register it is as follows:
protected void Page_PreRender(object sender, EventArgs e)
{
string addClickFunctionScript = #"function addClickFunction(id) {
var b = document.getElementById(id);
if (b && typeof(b.click) == 'undefined')
b.click = function() {
var result = true;
if (b.onclick) result = b.onclick();
if (typeof(result) == 'undefined' || result)
eval(b.getAttribute('href'));
}
};";
string clickScript = String.Format("addClickFunction('{0}');", lbHello.ClientID);
Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true);
Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + lbHello.ClientID, clickScript, true);
}
Page Markup -
The page mark-up is the same for both of the aforementioned solutions:
<asp:Label runat="server" ID="lblHello" />
<asp:Panel ID="Panel1" runat="server" DefaultButton="lbHello">
First name:
<asp:TextBox runat="server" ID="txtFirstName" />
<asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click"
OnClientClick="javascript:alert('Hello, World!');"/>
</asp:Panel>
In both cases a custom control is not needed to achieve this type of functionality. Keep it simple.
Take a look at this
<asp:Panel runat="server" DefaultButton="lbHello">
First name: <asp:TextBox runat="server" ID="txtFirstName" />
<asp:LinkButton ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" />
</asp:Panel>
The rest of the answer can be found here. It shows how to fix the problem that arises with FireFox
http://kpumuk.info/asp-net/using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net/
Another approach could be to fake the onclick event like this.
jQuery(document).ready(function () {
jQuery('#<%= txtFirstName.ClientID %>').keypress(function (event) {
if (event.keyCode == 13) {
eval($('#<%=lbHello.ClientID %>').attr('href'));
}
});
});
The downside is that you need to use this for all places you need to make default buttons.
See this
Link Button on the page and set it as default button, work fine in IE but not in Mozila
The dummy button answer is the cleanest solution IMO.

Resources