I have performance issue on website, because of too long viewstate in source code. on some pages it's size is more than 15-20kb. Which is increasing the load time on browser.
Is there any way to disable viewstate partially or fully without any harm on other module of website. FYI there is one listview and one form on these example pages. where viewstate is very long.
More Example pages
http://www.pricingindia.in/coupons/ebay-in-coupon-codes-20
http://www.pricingindia.in/coupons/flipkart-coupon-codes-32
You probably want to disable for ViewState for your Page in general, and then only enable ViewState for the controls that need / use it.
See this MSDN page on the Control.ViewStateMode property, it describes how to set that up:
To disable view state for a page and to enable it for a specific
control on the page, set the EnableViewState property of the page and
the control to true, set the ViewStateMode property of the page to
Disabled, and set the ViewStateMode property of the control to
Enabled.
You will need to do some testing to see which controls need / use the ViewState in your specific app. But, basically,
anything that's static, you can disable the ViewState (Buttons, LinkButtons, etc).
Any controls whose state doesn't need to be restored between PostBacks, you can disable ViewState (such as a TextBox in a form that is submitted to the server, and then cleared).
Any controls that need to keep their state between PostBacks, you want to enable Viewstate (this would often be databound controls like GridViews / etc).
Doing this should definitely reduce the load that ViewState is putting on your pages.
Okay, I couldn't leave well enough alone:
Firebug said the following bit of code blocked the site from rendering for about 6 seconds. I thought it was the jsapi (based on info from chrome's tools) but the following returned a "502 Bad Gateway" message meaning that it sat there spinning it's wheels unable to process while preventing your web page from displaying.
I would move the <script .. call to the header, where it belongs. Then I'd move the google.load and google.setOnLoadCallback to the bottom of the web page so it runs last.
Finally I'd figure out exactly why it's failing to work right.
Homework for you: get Firebug loaded into firefox and learn how to use it's Net tools to see where site loading issues are.
<div class="sr_bx1 FL clearfix">
<div class="FL searchbg">
<div id='cse' style='width: 100%;'>Loading</div>
<script src='http://www.google.com/jsapi' type='text/javascript'></script>
<script type='text/javascript'>
google.load('search', '1', { language: 'en', style: google.loader.themes.V2_DEFAULT });
google.setOnLoadCallback(function () {
var customSearchOptions = {};
var orderByOptions = {};
orderByOptions['keys'] = [{ label: 'Relevance', key: '' }, { label: 'Date', key: 'date'}];
customSearchOptions['enableOrderBy'] = true;
customSearchOptions['orderByOptions'] = orderByOptions;
var imageSearchOptions = {};
imageSearchOptions['layout'] = 'google.search.ImageSearch.LAYOUT_POPUP';
customSearchOptions['enableImageSearch'] = true;
customSearchOptions['overlayResults'] = true;
var customSearchControl = new google.search.CustomSearchControl('010882286766777081969:xkox132izzk', customSearchOptions);
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.setAutoComplete(true);
customSearchControl.draw('cse', options);
}, true);
</script>
</div>
Using Page Adapter Class, you can solve this problem. I found following solution helpful for ASP.NET Web Application:
view state serialization is handled by an object of type PageStatePersister. (The PageStatePersister class is an abstract class that defines the base-level functionality for serializing view state to some persistent medium.)
Steps:
1) In Your Web Application, Add Folder: App_Browsers
2) In this folder, Add new BrowserFile: ViewStateAdapter.browser
3) Write following code in it:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page" adapterType="ServerSideViewStateAdapter" />
</controlAdapters>
</browser>
</browsers>
4) In Your WebApplication, Add Folder: App_Code
5) In this folder, Add new ClassFile: ServerSideViewStateAdapter.cs
6) Write following code in it:
using System;
using System.Web.UI;
using System.Web.UI.Adapters;
public class ServerSideViewStateAdapter : PageAdapter
{
public override System.Web.UI.PageStatePersister GetStatePersister()
{
return new SessionPageStatePersister(this.Page);
}
}
You can refer this video, it can help you:
https://www.youtube.com/watch?v=36pmFySbXZA
Related
I am currently writing a ContentManager in ASP.NET. I have a preview button which uses jQuery to post the form data to new window and shows how a page would look without saving it to the database and effecting the live site. Although its been somewhat of a hassle to get ASP.NET to post directly to the page I am trying to preview, I've finally worked it all out using a series of jQuery code. It worked beautifully, I loaded all the post values into the page using Request.Form and displayed them on the page. Unfortunately for some reason the Telerik RadEditor's I was using were posting me the values they had been assigned on the C# Page_Load event and did not reflect the text changes I made. If anyone could help me out that would be great.
function showPreview()
{
url = "<%= (SiteManager.GetSite()).Url + this.Filename %>?preview=true";
var specs = "width=1010,height=700,location=0,resizeable=1,status=1,scrollbars=1";
window.open(url, 'PagePreview', specs).moveTo(25, 25);
$("#__VIEWSTATE").remove();
$("#__EVENTTARGET").remove();
$("#__EVENTARGUMENT").remove();
$("#aspnetForm").removeAttr("action");
$("#aspnetForm").attr("target","PagePreview");
$("#aspnetForm").attr("action", url);
$("#aspnetForm").submit();
}
Here is all the post data I am receiving from the tererik RADEDITOR ::
[ctl00_MainContentPlaceHolder_SideContentRadEditor_dialogOpener_Window_ClientState] => [ctl00_MainContentPlaceHolder_SideContentRadEditor_dialogOpener_ClientState] => [ctl00$MainContentPlaceHolder$SideContentRadEditor] => [ctl00_MainContentPlaceHolder_SideContentRadEditor_ClientState] => [ctl00_MainContentPlaceHolder_ContentRadEditor_dialogOpener_Window_ClientState] => [ctl00_MainContentPlaceHolder_ContentRadEditor_dialogOpener_ClientState] => [ctl00$MainContentPlaceHolder$ContentRadEditor] => %3cp%3eTestPageContent%3c/p%3e
This is the html value of the text editor (shown above) %3cp%3eTestPageContent%3c/p%3e
This is the value in the RadEditor that was loaded during the Page_Load event.
I changed the value to "Test". But it was not sent over the POST Request, it sent what was loaded in the page load.
The editor content area is separate from the textarea used to submit the content during a POST request. The editor will automatically try to save the content in the hidden textarea when the form is submitted, but in your case no event is fired because it happens programmatically (i.e. you call .submit()). You will need to tell the editor to save its content manually before you do the postback. The code is pretty basic - get a reference to the editor and call .saveContent():
//Grab a reference to the editor
var editor = $find("<%=theEditor.ClientID%>");
//Store the content in the hidden textarea so it can be posted to the server
editor.saveContent();
One solution would be to grab the current HTML in the editor in your showPreview method and pass that manually. To do that, add a hidden input element in your page to hold the HTML content:
<input type="hidden" id="htmlContent" name="htmlContent" />
Then, you can set that intput's value in showPreview like this:
function showPreview()
{
url = "<%= (SiteManager.GetSite()).Url + this.Filename %>?preview=true";
var specs = "width=1010,height=700,location=0,resizeable=1,status=1,scrollbars=1";
window.open(url, 'PagePreview', specs).moveTo(25, 25);
$("#__VIEWSTATE").remove();
$("#__EVENTTARGET").remove();
$("#__EVENTARGUMENT").remove();
// *** Begin New Code ***
//Grab a reference to the editor
var editor = $find("<%=theEditor.ClientID%>");
//Get the current HTML content
var html = editor.get_html()
//Put that HTML into this input so it will get posted
$("#htmlContent").val(html);
// *** End New Code ***
$("#aspnetForm").removeAttr("action");
$("#aspnetForm").attr("target","PagePreview");
$("#aspnetForm").attr("action", url);
$("#aspnetForm").submit();
}
Then when you want to get the HTML during the postback you can just use Request.Form["htmlContent"]
One caveat: Since you'll be posting raw HTML, ASP.NET's Request Validation might cause problems. One of the major purposes of that validation is to make sure that HTML content doesn't get posted back to the server - the very thing you're trying to accomplish. You could of course turn the validation off (see the link above) but the validation is there for a reason. Another solution might be to do some basic encoding of the HTML before you post it. If you just replace all less-than symbol (<) with something before posting it, ASP.Net will be happy. Then you just need to 'un-replace' it during the postback.
just need tips on how to make forms where request are submitted via AJAX with a loading progress image. I am using update panels with AJAX framework. I would like to know about the recommended approach. Through JQuery or AJAX toolkit ?
Please advice, examples would be an added bonus for me.
1- Prepare a client side div with "display:none" style property. put your loading image inside.
2 - when the user or page submits a request, change that divs display property to "block".
3- Add some kind of "information received" sign to the response and check this response from the client side and then change that divs display property back to "none"
I would like to know about the
recommended approach
Well, that depends on what you are doing, what parts of the form are you updating, how big is the form, what values are you sending to the server.
Generally speaking, if you want to update something simple (dropdownlist, listbox, etc), youd generally use JavaScript (or jQuery) to call an AJAX-enabled web service. This way, you're only sending to the server the data it needs, things like ViewState/cookies are not sent over the wire. You also have full control over the pre/post execution events (so you can add your loading images, call the WS, then clear them).
However, if you want to asynchronously update an entire form (which has a lot of controls), you're probably right in using an UpdatePanel. Things like a GridView are a good case for an UpdatePanel (as you usually need to handle editing, binding and paging all asynchronously).
The progress image is made easy with the following code:
<ProgressTemplate>
<img src="someloadingimage.gif" alt="Loading" />
</ProgressTemplate>
Stick that inside your UpdatePanel, and whenever an AJAX call is made, the loading image will be shown.
HTH
If you use JQuery for AJAX request then you can use the following events -
$.ajax({ url: "test.html",
type: "GET",
beforeSend: function(){
-----load your loader here-----
});,
success: function(){
------remove your loader here -----------
Remaining code
}});
You can also use POST. in above example i have used GET.
For detailed documentation you can refer - http://api.jquery.com/jQuery.ajax/
Create a small plug-in for your loader like so.
$.fn.ShowLoader = function(on){
switch(on)
{
case true:
$(this).show();
break;
default:
$(this).hide();
break;
}
}
then use the following:
$('form').submit(function(){
var Form = $(this);
$('.loader',Form).ShowLoader(true);
//Gather some params
Location = Form.attr('src');
Data = Form.Serialize();
$.post(Location,Data,function(result){
result = result || false;
if(result)
{
$('.loader',Form).ShowLoader(false); //Disable the loader
//Process result
}
});
})
html would just be a regular form, with an image / div inside with the class of loader
In my website I'm using the standard ASP.NET menu control. I already got so far as to write a custom control adapter to get rid of the rather tacky html output that is generated by the default control adapter.
One thing keeps buggering me though. Somehow ASP.NET is generating extra javascript that I don't want nor need for my menu controls, since I won't be using any of the dynamic features in the control. I replaced the control adapter, so it doesn't generate compatible HTML for that.
Anyone got an idea how I can prevent ASP.NET from generating the extra javascript for the menu control?
This problem cropped up for me after upgraded to ASP.net 4.0 with the installation of vs 2010. The fix is to either force the menu to render as a table or to turn off the new CSS/javascript "features" that 4.0 adds. Settings the menu's RenderingMode attribute to "Table" fixed this problem for me even though I use a Menu Adapter to render the control with lists.
<asp:Menu ID="mnuStuff" runat="server" RenderingMode="Table">
...
</asp:Menu>
You can do this site wide setting controlRenderingCompatibilityVersion to 3.5 in the web.config:
<system.web>
<pages controlRenderingCompatibilityVersion="3.5"/>
</system.web>
This will eliminate the rendering of inline javascript that asp injects in the base of the page.
If you prefer to stick with ASP.Net 4.0 control rendering you can create a custom menu (derived from System.Web.UI.WebControls.Menu) and replace the OnPreRender:
public class MyCustomMenu : Menu
{
protected override void OnPreRender(EventArgs e)
{
// Don't call base OnPreRender
//base.OnPreRender(e);
}
}
That did the trick.
An alternative way to get rid of the menu startup script is to call RegisterStartup script method before the Menu PreRender event, using the same script key, and outputting dummy (or empty) script.
This relies on internal implementation details of the Menu Type discovered using Reflector, so is somewhat fragile.
For example, a static class that looks something like:
static MenuHelper
{
private static Type _rendererType =
typeof(Menu).Assembly.GetType(
typeof(Menu).FullName + "+MenuRendererStandards"
);
public static void RemoveMenuScript(Menu menu)
{
string dummyScript = "<!-- Removed Menu Startup script -->";
string key = "_registerMenu_" + menu.ClientID;
ScriptManager.RegisterStartupScript(menu, _rendererType, key, dummyScript, false);
}
}
You then just need to make sure you call MenuHelper.RemoveMenuScript(menu) before the menu's PreRender event.
The OP is using an Adapter so Tim Santeford's answer is better in his situation. But if you want to render a static menu as a list without the startup code, and without the effort of writing an adapter, this might be an alternative.
<script type="text/javascript">
Sys.WebForms.Menu = "";
</script>
it works..
use it in aspx page
I just plan to ask about a similar question after 2 hours of search and have no luck.
What I want is to use the jquery superfish plugin as I want its animation for smooth looking. And with the ASP.NET generated javascript, the superfish just won't work.
And finally I try to set the ASP.NET Menu's control's attribute Enabled = false
and the outcoming source becomes this:
new Sys.WebForms.Menu({ element: 'mysitemeun', disappearAfter: 500, orientation: 'horizontal', tabIndex: 0, disabled: **true** });
After tracing the code, setting it disabled still have some style changes in the Menu but it will not add event to the MenuItem. And the superfish's animation works now.
if (!this.container.disabled) {
Sys.WebForms.Menu._domHelper.addEvent(this.element, 'mouseover', Sys.WebForms.MenuItem._onmouseover);
Sys.WebForms.Menu._domHelper.addEvent(this.element, 'mouseout', Sys.WebForms.MenuItem._onmouseout);
}
My requirement is to have database based help system for asp.net website, as shown in the image below. i have searched web but could not find even remotely related solution.
DNN Help System http://img3.imageshack.us/img3/6720/dnnhelpimage20091125.jpg
You could assign each help item a unique ID (perhaps GUID to make it easier to generate by the developer enabling help for that item).
Clicking on the link opens a dialog, tooltip, new window, whatever. Just have the UI load the help text by ID from the database.
To make this easier to implement in the UI, there are a few ways. Perhaps you can create a jQuery client-side behavior.
your HTML would look something like:
<span class="help" id="#{unique-id-here}">Admin</admin>
and you could have jQuery on DOM load:
$(function() {
var help = $(".help");
help.prepend("<img src=\"path/to/images/help.png\" />");
help.click(function() {
//do something with this.id; open a popup, a title bar, whatever.
}
});
We did it on our site by doing the following:
We have a HelpTopics database with a HelpTopicId and HelpTopicText
We create an aspx page that displays the HelpTopicText based on the HelptopicId passed in the querystring.
We set up a css class for the A tag that displays the link to the help with the question mark image.
We created a UserControl named TitleandHelp that contained a link to the page mentioned in step 2 and the style for the link set to step 3 above: The usercontrol has a public rpoperty for the title and one for the topicID (We called it HelpContext).
We add the usercontrol to the aspx page where appropriate
<uc2:titleandhelp ID="titleandhelp1" runat="server" HelpContext="4" PageTitle="Forgot Password" />
it may sound like a lot of work, but really it only takes a half hour or so to do all of the setup. The rest of the work lies in populating the table and dragging the usercontrol onto the pages where appropriate.
I have an ASP.NET server control which relies on JQuery for certain functionality. I've tried to add as a webresource.
My problem is my method of including the jquery file adds it to the body, or the form to be exact:
this.Page.ClientScript.RegisterClientScriptInclude(...)
The alternative to this is to add it as a literal in the head tag:
LiteralControl include = new LiteralControl(jslink);
this.Page.Header.Controls.Add(include);
The problem with this however is any existing code srcs in the head which use JQuery fail, as JQuery is loaded afterwards (ASP.NET adds the literal at the bottom of the control tree).
Is there a practical way of making JQuery an embedded resource, but loaded in the head first? Or should I give up now.
If you want to package up jQuery and embed it inside your own server control you should serve it to the client using the ScriptManager. From the top of my head you have to:
add jQuery.js to your project
under its "Build Action" Property,
make it an Embedded Resource
in the AssemblyInfo.cs for your
control add
[assembly: WebResource("<Your Server Control namespace>.jQuery.js", "application/x-javascript")]
Make your control inherit from
System.Web.UI.ScriptControl (or at
least implement IScriptControl)
Override GetScriptReferences:
protected override IEnumerable<ScriptReference>
GetScriptReferences()
{
return new ScriptReference[] {
new ScriptReference("<Your Server Control namespace>.jQuery.js", this.GetType().Assembly.FullName),
};
}
All of your own client script should be setup inside:
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
Which will then ensure the correct order of dependencies (ie jQuery will be available to your own client script).
Update:
A far easier way of doing it is to simply add the script tag dynamically, in your script and point to the google code hosting. e.g.
function include_dom(script_filename) {
var html_doc = document.getElementsByTagName('head').item(0);
var js = document.createElement('script');
js.setAttribute('language', 'javascript');
js.setAttribute('type', 'text/javascript');
js.setAttribute('src', script_filename);
html_doc.appendChild(js);
return false;
}
include_dom("http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js");
The function is taken from this article
Crecentfresh pushed me in the right direction, I also found
http://en.csharp-online.net/Creating_Custom_ASP.NET_AJAX_Client_Controls—IScriptControl.GetScriptReferences_Method.
My problem still remains though, the ScriptManager adds the references after the script in the head but I think this is an issue that can't be resolved. I've opted to answer myself but also upvoted crescentfresh.