Fragment Cache a user control in asp.net webform Masterpage - c#

I had a Masterpage which uses as sidebar for navigation .I created a user control for that sidebar as each user will have their own set of navigation menus.
Inside my UserMenu I use Infragistic webexplorer and Iam creating each item of webexplorer using ado.net result from database dynamically.
Everything is working fine .in high bandwidth but in low bandwidth it takes 3-4 seconds for the menubar to load.causing users to wait so much on each postback.
So I tried fragment caching .but i seems not working.can you suggest me whats wrong
In masterpage I did
<div>
//this is my usercontrol
<uc1:DynamicMenuBar runat="server" id="DynamicMenuBar" />
</div>
<div id="main" class="content" >
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
<div class="bodybackground">
</div>
</asp:ContentPlaceHolder>
</div>
In my usercontrol .ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="DynamicMenuBar.ascx.cs" Inherits="ArtWebApp.DynamicMenuBar" %>
<%# Register assembly="Infragistics35.Web.v12.1, Version=12.1.20121.2236, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb" namespace="Infragistics.Web.UI.NavigationControls" tagprefix="ig" %>
<%# OutputCache Duration="600" VaryByParam="none" %>
<ig:WebExplorerBar ID="WebExplorerBar1" runat="server" Width="250px">
</ig:WebExplorerBar>
And in my usercontrol .ascx.cs I had done the below
public partial class DynamicMenuBar : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadexplorerebar(); //this function creates the groups and childs based on the database result dynamically
this.WebExplorerBar1.EnableViewState = true;
}
}

I believe Page_Load will still be called even if the uc is cached. Try checking to see if it's in the cache before calling loadexplorerebar(). It'll be null if it's not in the cache.
So try changing:
if (!IsPostBack)
to:
if (!IsPostBack && WebExplorerBar1 == null)

It seems to be the internet problem. Try using AJAX call instead of server code for menu retrieval

Related

ASP.NET Webform OnClick event not firing properly

I have a Default page (initial landing page) with a bunch of asp controls and everything works great. I also have an Admin page with one asp button control (I simplified for the post). Both are wrapped in form element on a Site.Master page. The button click event does not fire on my Admin page. Here is my button event and page code/code behind:
Page code
<%# Page Title="Admin1" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="Admin1.aspx.cs"
Inherits="HPRMWebClientReporting.Admin1" %>
<asp:Content runat="server" ID="AdminContent"
ContentPlaceHolderID="AdminContent">
<asp:Button ID="ButtonGo" runat="server" Text="Button" Width="111px"
OnClick="ButtonGo_Click" />
</asp:Content>
Code Behind
public partial class Admin1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void ButtonGo_Click(object sender, EventArgs e)
{
this.Context.Items["Msg"] = "It worked!!!.";
Server.Transfer("MessagePage.aspx");
}
}
Here is what happens:
Goes through Page_Load of Default page
Goes through Page_Load of Site.Master page
Refreshes my site and shows the Default page
At no point does it go my click event or Page_Load of my Admin page when the button is clicked? The button click should be taking it to the MessagePage page.
This is driving me crazy. I did try turning Causes Validation to false on the button with no luck. Any ideas?
Note: Also, maybe this will help someone determine what I'm doing wrong. I changed the Page Code so it does not use the MasterPageFile Site.Master and I just wrapped the button in its own form element and it worked fine but I don't want it to work that way as I want to use the Master page.
I found something that worked although I am not entirely sure why without further research. In my Site.Master page and in the form element I mentioned in the post I pulled out the action="/" and now my controls work on Admin page as I expected them too.
<form id="Form1" action="/" method="post" runat="server">
<asp:ContentPlaceHolder ID="HomeContent" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="ContactContent" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="AboutContent" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="AdminContent" runat="server">
</asp:ContentPlaceHolder>
</form>

How to change the form action in C# .NET through code?

I am working on a project in C# .NET that allows me only one form in the .aspx file.
<form id="form1" runat="server" action="#1">
How can I change the form action through the C# code in a method?
I have tried this:
protected void Button1_Click(object sender, EventArgs e)
{
form1.Action = "#2";
}
but it didn't work. Thanks in advance...
Based on the comments to you question. asp:Panel Controls could help you out.
A very rough example
ASPX:
<form id="form1" runat="server">
<asp:Panel id="Form1" runat="server">
<!-- Form 1 Stuff -- >
<asp:Button ID="Button1" runat="server" Text="Submit"
OnClick="Button1_Click" />
</panel>
<asp:Panel id="Form2" runat="server" Visible="false">
<!-- Form 2 Stuff -- >
<asp:Button ID="Button2" runat="server" Text="Submit"
OnClick="Button2_Click" />
</panel>
</form>
C#
protected void Button1_Click(object sender, EventArgs e)
{
//HIde "Form"1
Form1.Visible = false;
//Show "Form"2
Form2.Visible = true;
//Do other stuff
}
protected void Button2_Click(object sender, EventArgs e)
{
//Do Final Processig
}
Also look at the DefaultButton property of the Panel
(Moving this to the top because it's an answer to the newly understood question. It's not how to change the form action, but how to have multiple forms.)
If you want a server form on a page that already has a server form then perhaps that second "form" should be a User Control. That way it sits inside the host page's server form but doesn't require its own form. And it's self-contained, able to contain whatever logic it needs when handling a postback.
Here's an example of a simple User Control. You can create one from Add > New Item > Web > Web Forms User Control.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="OtherForm.ascx.cs" Inherits="WebApplication1.OtherForm" %>
<label for="<% = OtherFormTextInput.ClientID %>">
This is some other form on the same page
</label>
<asp:TextBox runat="server" ID="OtherFormTextInput"></asp:TextBox>
<asp:Button runat="server" ID="Submit" Text="Submit this other form"/>
It looks like an .aspx page but it has no form. It can still have its own code behind which can interact with with the other server controls it contains, just like an .aspx page would.
Then you add that control to your "main" page:
<%# Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!-- Register the user control -->
<%# Register TagPrefix="uc" TagName="other" Src="~/OtherForm.ascx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<!-- This form has its own stuff, but also contains the "other" form. -->
<uc:other runat="server" ID="TheOtherForm"></uc:other>
</form>
</body>
</html>
I recommend this over using panels (which still works) because if you're putting two forms on one page, it's likely that you might at some point want to move the secondary form to another page or re-use it. This approach keeps it completely self-contained. Its code-behind isn't in the same file as the the .aspx page. You can place this on as many pages as you want.
Original "literal" answer which addresses the question as originally understood.
The runat="server" form exists entirely for the purpose of allowing ASP.NET to interact with the page and its server controls during postbacks. It's central to the way webforms works. If you change the action then technically what you have isn't a webforms page any more.
That's fine (I don't even like webforms) but it can lead to some weird behavior. If you have controls that trigger postbacks then normally they'd be handled on the same page and your user would just see a (hopefully) fast refresh. Now they might get sent to another page.
What if you just removed that form entirely and added your own form instead? Then your .aspx page will just behave more like an .html page.
Having added all the disclaimers about why not to do it, you can change the action using JavaScript. Here's a sample:
<%# Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" ClientIDMode="Static">
<asp:Button runat="server" text="Causes postback"/>
<asp:CheckBox runat="server" AutoPostBack="True"/>
</form>
<script>
document.getElementById("form1").action = "http://stackoverflow.com";
</script>
</body>
</html>
Some browsers might not allow changing the form's action.
I put the checkbox there just for fun (I must be really bored) to show the odd side effects it could have, that you might click on a checkbox and get redirected to a different page.
You can write a response.write() in your Asp.net side that print some javascript or jQuery code! As #Scott Hannen wrote some javascript like this :
Response.Write("<script>document.getElementById('YOURFORMID').action = 'YOUR URL';</script>");
or with jQuery
Response.Write("<script>$('#YOUR FORM ID').attr('action', 'YOUR URL');</script>");
btw if you have access to .html or .js files u can directly put this jQuery code without any C# code!

Creating form tag programmatically not working

I have a simple web page that contains a Literal, now I want to create a form tag in code behind.
This is an example:
if (IsPostBack)
{
Literal1.Text = "form submit";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx'
method='POST'><input type='submit' value='click here'/></form>";
}
This code create the form, but when I click the submit button, it doesn't go through IsPostBack path. Why?
Note that I need it to be created and sent as an string, because I want to use it in ajax for example.
IsPostBack is only enabled when the POST request originates from ASP.NET's __doPostBack() function. See How to use __doPostBack() for how to create an async postback request with JavaScript.
An ASP.NET web form is already an HTML form and encompasses all of your controls. You are nesting a form within a form which is not legal HTML.
I'd suggest you replace your nested form with a simple button. In the click handler for the button, redirect to default.aspx.
As indicated by John Wu, you don't want to implement your code this way. Nested forms -- while browsers forgive them -- are just not the way to go, especially with ASP.Net WebForms. Sure, I was able to get your code to work, BUT if you need to ajaxify your page so that it works with the WebForms postback model, then it would be much better to use the UpdatePanel control (in conjunction with the ScriptManager control).
ASP.Net WebForms is predicated on only having a single Form element used on a page, as it relates to its postback model, so you'll want to work within that constraint.
Here's some code to demonstrate the use of the UpdatePanel to ajaxify a WebForm (and take advantage of PostBack):
...the .ASPX page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NestedForm_Question.aspx.cs" Inherits="StackOverflowAspNetQuestionAnswers.NestedForm_Question" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Literal ID="Literal1" runat="server" />
<asp:Button ID="SubmitButton" Text="Submit" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
...the associated code-behind class:
public partial class NestedForm_Question : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SubmitButton.Click += SubmitButton_Click;
}
void SubmitButton_Click(object sender, EventArgs e)
{
Literal1.Text = "form submit";
}
}
You can see that in the code-behind class, the code that would need to be written to set the value of the literal control after the Button is clicked is the same whether the page is ajaxified or not.
I've changed my code to this:
if (Context.Request.Form.HasKeys()) // instead of if(IsPostBack)
{
Literal1.Text = "isPostBack";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx' method='POST'><input type='submit' name='submitbtn' value='click here'/></form>";
}
Using different examples, I didn't find any exception to this. and it works well.
Any idea about this solution?
Note that in this way at least one of our elements in the form should have the name property.

ASP.NET 4.0 C# "state information is invalid for this page and might be corrupted." MasterPage->Aspx->Ascx

This is my first SO post, so please forgive any faux pas. I feel as though I've tried everything on every post related to this error (disable viewstate, noCache, etc) and I'm at my wits end.
I have a blank project with a single master page, a single page, and a single control.
The page (aspx) loads using the master page. This works fine. There is a button on the page which loads the control (the ascx) onto the aspx in the section called divRightMainView. This also works fine (which is where my problem seems to differ from all others I've found...). There is a button on the ascx which is supposed to call the code-behind of the ascx - this is where I get the "state information" error.
This is the aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" EnableEventValidation="false" AutoEventWireup="true" CodeBehind="Outer.aspx.cs" Inherits="TestProject.Outer" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<script type="text/javascript">
function loadUserView(viewToLoad) {
PageMethods.RenderControl(viewToLoad, onSuccess, onError);
}
function onSuccess(results) {
alert(results);
var command = results.split('##')[0];
if (command == 'loadView') {
var htmlToLoad = results.split('##')[1];
$get('divRightMainContentView').innerHTML = htmlToLoad;
}
}
function onError(error) {
alert('error ' + error);
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="ScriptMgr" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
<div id="leftSideContent">
<input type='button' id="clickToLoadASCX" value="Click Me" onclick="loadUserView('/inner.ascx');"/>
This is the "Outer.aspx" page which will hold the ascx after the button is clicked
</div>
<div id="divRightMainContentView">
</div>
</asp:Content>
Aspx code behind (which renders the ascx)
[WebMethod]
public static string RenderControl(String controlName)
{
Page page = new Page();
Control control = page.LoadControl(controlName);
HtmlForm form = new HtmlForm();
form.Controls.Add(control);
page.Controls.Add(form);
StringWriter writer = new StringWriter();
HttpContext.Current.Server.Execute(page, writer, false);
return "loadView##" + writer.ToString();
}
This is the ascx called inner.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="inner.ascx.cs" Inherits="TestProject.inner" %>
<div>
This is the inner text. When I click the button below I should proceed to inner.ascx.cs to the "PageBehindCall_Submit".
<asp:Button ID="innerButton" runat="server" onclick="PageBehindCall_Submit" Text="Submit"/>
</div>
And finally, the ascx code-behind
protected void PageBehindCall_Submit(object sender, EventArgs e)
{
string str = "This call does not work!";
}
I'm hoping to be able to use the "PageBehindCall_Submit" to process data, grab inputs from the ascx, etc. Let me know if there is a way to make this happen, or another possible work-around? Any help would be appreciated!
Why not load the ascx on page load of the ascx but turn the visibility off rather than manually rendering user control html. This is very weird that it does not hook up with the event in ascx as the control belongs to ascx. But I think you should add it in aspx then try to turn on visibility whenever you need it.

ASP.NET issue when removing Control on Page Load

I have following Index.aspx web form:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ProblematicWebApplication.Index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<asp:Label ID="dummyLabel" runat="server" Text="This is dummy label." />
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="intDropDownList" runat="server"/>
<br />
<asp:Button Text="Submit" OnClick="OnSubmitClicked" runat="server"/>
<br />
Selected value: <asp:Label ID="selectedValueLabel" runat="server" />
</div>
</form>
</body>
</html>
And following code behind Index.aspx.cs file:
using System;
using System.Linq;
namespace ProblematicWebApplication
{
public partial class Index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.intDropDownList.DataSource = Enumerable.Range(0, 11).ToArray();
this.intDropDownList.DataBind();
}
if (this.Request["remove-dummy"] != null)
this.Controls.Remove(this.dummyLabel);
}
protected void OnSubmitClicked(object sender, EventArgs e)
{
this.selectedValueLabel.Text = this.intDropDownList.SelectedValue;
}
}
}
When I run my application with no remove-dummy parameter in query string and select some value from intDropDownList and click Submit button, selected value is accordingly presented in selectedValueLabel.
But if I run my application with remove-dummy=1 parameter in query string, dummyLabel gets removed. Now when I select some value from intDropDownList and click Submit button, selected value is not correctly written to selectedValueLabel and all items from intDropDownList are removed.
Can someone explain it to me why this is happening?
Why removing unrelated dummyLabel control has influence on intDropDownList control?
Hmm, seems odd. I got it to work by moving your code that removes the control into the Page's PreInit event:
protected void Page_PreInit(object sender, EventArgs e)
{
if (this.Request["remove-dummy"] != null)
{
this.Controls.Remove(this.dummyLabel);
}
}
It seems that ViewState loading fails in postback after dummyLabel is removed in previous page load.
Details:
first study following articles:
TRULY Understanding ViewState - Infinities Loop
ASP.NET Page Life Cycle Overview
Following image shows important ASP.NET page events and where in between ViewState handling takes place.
So what happens when declarative Control dummyLabel is removed? Here is a process:
Page is requested for the first time with query string parameter remove-dummy=1.
In Page_Load event declarative Control dummyLabel is removed.
Before SaveStateComplete event, ViewState is saved. There is no control dummyLabel in control tree, so its ViewState won't be saved.
Submit button is clicked.
Between InitComplete and PreLoad events, ViewState gets loaded. This is where it breaks because control tree now contains dummyLabel (dummyLabel gets removed after, in Load event) and ASP.NET fails in recursively loading ViewState into Page control tree. My assumption is that ViewState and Page control tree are tightly coupled and recursive ViewState loading fails as a consequence of this tight coupling.
One more situation that backs-up this theory: if you place dummyLabel at the very end of the page, issue doesn't happen anymore, because all other controls in Page control tree that come before dummyLabel already picked correct values from ViewState (ViewState structure and Page control tree are tightly coupled). If there were more controls after dummyLabel, their ViewState loading would fail.
To resolve this issue, all declarative Controls (defined in ASPX file) that should be removed, must be removed before ViewState loading takes place - in InitComplete event or any other event before it.

Categories