Ok, so the problem is as follows: I'm using jQuery's AJAX in order to make behind the scene calls within the page (on events such as voting an item) and changing the content in the appropriate element. The problem occurs when I mix AJAX with ASP.net's AJAX, more precisely when I try to do a postback AFTER I've used jQuery on the page to perform an action. The page's viewstate is changed and validation fails (which would seem somewhat normal as a matter of fact).
My question is: can I disable the validation somehow so that I can perform postbacks combined with the chaged page viewstate? So far searching on how to disable it yielded no results.
A more practical example is on a comments page where I allow voting the comments and posting new comments as well. So should a user vote a comment and THEN post his own, the page's contents is changed, and thus validation fails. Also, I've tried placing the comment form within an update panel as to prevent the entire page from posting, but it still fails.
Of course I could use an alternate route and have a different page for handling the event and just call that via jQuery's AJAX, but I was wondering if I could do this by combining ASP.net and jQuery.
Thanks in advance.
If you want to disable viewstate verification, you can set it at the page or config level by using Page.EnableViewStateMac = false.
http://msdn.microsoft.com/en-us/library/system.web.ui.page.enableviewstatemac.aspx
It's not necessarily a good idea though because the validation functionality is there to protect from viewstate tampering, which you'll be turning off...
If you're running into issues with invalid viewstate because of jQuery ajax calls, one option is to consider using the Ajax controls, such as the UpdatePanel. You can wrap certain controls and mark the UpdatePanel as conditional to ensure a small round trip. This will not interfere with viewstate and allow you to continue to use viewstate validation and ajax at the same time.
There may be ways to use jQuery ajax calls and not interfere with viewstate validation. Others may be able to highlight this approach.
Related
I currently have a simple form that when you click the "save" button will persist it to the database.
I would like to use JQuery to do the callback for me and popup a "Save completed" div window/div of some sort.
My only problem is how do I call the btnSave_Click() event from JQuery?
If I use PageMethods the method would have to be static and therefore lose access to my textboxes and other page controls?
Thanks,
Goosey
Are you explicitly trying to avoid passing the values of the input controls? because that would be much easier.
Using a lightweight jQuery call to do the post but then expecting a full control hierarchy in the code behind to pull data out? What's the intent here? If you require that, it would probably be easier just to submit the page, and register javascript to run to pop the success message up on load.
Personally, I think the page method route and $.ajax or $.post is a much cleaner, separate way to solve the issue. That way you can just show the popup as part of the success callback.
You can use onClientClick
Have a look at the jQuery Form Plugin, it can change existing forms into Ajax forms.
You need to set __EVENTTARGET to the id of the control that you want to simulate causing the postback if you want to use the same handler. I seem to recall having to replace the underscores with dollar signs as well, but I could be wrong on that. The hidden inputs, __EVENTTARGET and __EVENTARGUMENT, are used by the framework to identify which control caused the postback. There's a nice discussion of the server side issues in this blog post, though it doesn't talk about AJAX. Google for __EVENTTARGET and postback for more info.
ASP.NET has a number of nice features regarding making data input pages:
Adding input controls is easy (<asp:...).
The system automatically generates member variable for the controls.
Post-backs automatically populate the members variable with the returned values.
and some not so nice bits
post-backs seem to be tied to JavaScript for even the simplest of cases. For instance, with statically defined pages, using only basic controls, that are known at compile time.
My questions:
Is is possible to get the first list without the second?
What features does that JavaScript give the user?
What does that JavaScript actually do?
What is the technical reasons that it's used even in trivial cases?
As it happens my assumption were in error: See here
It really depends on the types of controls you are trying to use here -- the only ones that implement javascript are those that can't natively cause a postback (ie, an input/submit button are the only two that can). If you are using a LinkButton, ImageButton, or anything that you set "AutoPostBack = true" on will turn javascript on in order to cause a postback.
Other controls can also potentially use javascript if they are more advanced such as the Calendar. The technical reason for using javascript here is to provide automated postback when the controls require more advanced server interaction -- think about it, a link is meant to only ever be a link and if we're trying to make it operate as a button we have to force it to do just that through javascript interaction.
So that being said, yes you can definitely use ASP.NET without it having javascript you just have to avoid the controls that implement it by including functionality you couldn't possibly have without it. You can just as easily add HTML controls and add the runat="server" attribute and gain member variables to the control from code-behind.
Here's what came to my mind:
What features does that JavaScript give the user?
Client side validation.
What does that JavaScript actually do?
For exmaple, it ensures that the correct (server-side) event handlers are called, by setting the __EVENTTARGET hidden field.
Is is possible to get the first list without the second?
You can use normal HTML controls instead of the ASP.NET controls. Then on the server-side, you can read the control's values from the Form collection.
I assume you mean the javascript associated with an <asp:Button /> control, right?
In addition to the reasons mentioned by Fooberichu, the javascript can also help with ASP.NETs client side validation framework.
But I think it's primary use is to alert the framework what events it should fire on the postback in the page behind.
So if you had two buttons on the form, SaveButton and DeleteButton, the javascript helps the framework know whether it should execute the SaveButton_Click event or DeleteButton_Click event.
Hope this helps.
I need the ability to temporarily turn off the partial page update behavior for an ASP.NET Ajax / UpdatePanel based page. (The reason is to circumvent the issue where IE blocks "automatic file downloads" for downloads generated as a result of this postback, but I don't want to distract from my original question)
I looked at the client side javascript libraries hoping to find a switch somewhere. I think a solution might involve using javascript to override the 'onclick' event handler for the control that acts as the trigger, and then calling "submit" on the form itself..
Also, using the EnablePartialRendering property on the server-side ScriptManager control won't work because that is done when the page is being built. I need to be able to do this as a result of switching a drop down list box.
Any ideas?
Cheers!
/ Sean
Well, after much trial and error, I found two approaches that seemed to work:
Use Javascript to manually submit the top level form associated with the page. This usually has the ID of "form1".
Create a button that is outside of any UpdatePanels and use Javascript to click the button.
I wound up using the second approach, since it allowed me to handle the event with a specific routine without the need to guess that my postback came from a Javascript call.
This is an example of the code that performed the postback:
...
if (isDownload) {
document.getElementById('FullPostbackSubmitter').click();
return;
}
...
Hope this helps someone else!
You can set the EnablePartialRendering property of your ScriptManager to false.
For example,
If I have a textbox with runat=server on a page, The value will be posted back to the server so I can access the properties in the code-behind.
However, under the following situations, does it still hold true?
A textbox with runat=server but does not appear in the function that is post back to. For example, a button is also on the page, when clicked a post back occurs and within the method that is raised, this textbox was not used.
Within a MasterPage, will a textbox residing on the Masterpage itself be posted back?
Because just thinking, isn't this mechanism bloated in nature?
If all input controls and its value are posted back on every single button click (even when the input control is not needed), doesn't this deteriorate performance?
Having just one Form Tag on the page really restricts us to using this mechanism?
Truly Understanding ViewState is a must read article on the subject of ASP.NET ViewState
There are several options to cut down on the bloat (and yes, there's a lot of it when dealing with lots of controls):
Use AJAX to post only the items required - although be careful to allow clients that don't have JavaScript enabled to still use the page/ site.
The MVC framework allows multiple form tags to be used so you can group sections if needs be.
Set the EnableViewState to false on pages/ controls.
Break up your pages into smaller ones.
Additionally, check out this brilliant graphical representation of the Page Life Cycle in ASP.NET.
Every input on the page is posted back fully unless you use ajax, because of the single form tag. Welcome to asp.net...
As long as the method that you're hitting on the server-side is a non-static member of the page's class, it'll have access to the textbox and all other controls on the page.
And yes, all controls rendered to the browser (whether in the MasterPage, user control, etc.) will be available on post-back.
You may want to look into Understanding ASP.NET View State.
There surely are performance hits with this architecture, but (depending on complexity of the page) it's usually not an issue from the server load perspective, because hardware upgrades are typically cheaper than additional programming hours spend on optimizing application performance.
With that said, (and as others have pointed out) look into using AJAX if you want to avoid whole page-level postbacks to the server.
Yes, it's all posted back, and yes it can cause bloat. I'm sure if you search for ViewState you will find plenty of people ranting about it and how to minimise it :)
Yes your text box will be available in both cases, yes it is bloated. This is where AJAX comes into play. Using AJAX you can send just the data you need.
If you want to send a minimal ammount of data, you could use a Page Method (static method on page decorated so the script manager builds javascript to call it or you could call it using jquery or other methods), or a script enabled web service works nice as well.
You also have viewstate which can get very large. ASP.Net MVC is a new paradigm instead of using WebForms which doesn't have view state, or post backs. It embraces HTTP instead of hidding it giving developers more control.
The textbox data would be posted back as noted. In addition to using Ajax, disabling view state greatly imporoves your page's performance though even then data in properties critical to the functioning of controls (Control state) would still be posted back.
If you didn't have postback for every control on the form, you wouldn't be able to access it in code-behind. I.e. if in your button press you wanted to modify the property of the text control you couldn't do that because ASP.Net would know nothing about the text control.
Since the communication between the server and the client is stateless and every time a page is server the server forgets all about it Postbacks are important if you want to work with the same page again. No matter what programming language you use, this or similar mechanism exists for processing server side code.
If you wish to minimize postback (viewstate size), do this.
Set enableviewstate=false on all controls that you don't want posted back.
Use AJAX and web services wherever possible (and don't use UpdatePanel).
Use HTML control as much as possible instead of ASP.Net controls.
Hmm.. There are some excellent suggestion in other answers and good links too.
You've pretty much hit the nail on the head with vanilla ASP.NET - it's not very good! In both the instances you describe the answer is yes - the textbox will be sent with the form.
The whole postback/ViewState problem is a bit of a pain, one of the first things any competent ASP.NET developer learns to do is avoid them!
I have a problem with maintaining state in an ASP.NET AJAX page. Short version: I need some way to update the page ViewState after an async callback has been made, to reflect any state changes the server made during the async call.
This seems to be a common problem, but I will describe my scenario to help explain:
I have a grid-like control which has some JavaScript enhancements - namely, the ability to drag and drop columns and rows. When a column or row is dropped into a new position, an AJAX method is invoked to notify the control server-side and fire a corresponding server-side event ("OnColumnMoved" or "OnRowMoved").
ASP.NET AJAX calls, by default, send the entire page as the request. That way the page goes through a complete lifecycle, viewstate is persisted and the state of the control is restored before the RaiseCallbackEvent method is invoked.
However, since the AJAX call does not update the page, the ViewState reflects the original state of the control, even after the column or row has been moved. So the second time a client-side action occurs, the AJAX request goes to the server and the page & control are built back up again to reflect the first state of the control, not the state after the first column or row was moved.
This problem extends to many implications. For example if we have a client-side/AJAX action to add a new item to the grid, and then a row is dragged, the grid is built server-side with one less item than on the client-side.
And finally & most seriously for my specific example, the actual data source object we are acting upon is stored in the page ViewState. That was a design decision to allow keeping a stateful copy of the manipulated data which can either be committed to DB after many manipulations or discarded if the user backs out. That is very difficult to change.
So, again, I need a way for the page ViewState to be updated on callback after the AJAX method is fired.
If you're already shuffling the ViewState around anyway, you might as well use an UpdatePanel. Its partial postbacks will update the page's ViewState automatically.
Check out this blog post: Tweaking the ICallbackEventHandler and Viewstate. The author seems to be addressing the very situation that you are experiencing:
So when using ICallbackEventHandler you have two obstacles to overcome to have updated state management for callbacks. First is the problem of the read-only viewstate. The other is actually registering the changes the user has made to the page before triggering the callback.
See the blog post for his suggestions on how to solve this. Also check out this forum post which discusses the same problem as well.
I actually found both of those links you provided, but as noted they are simply describing the problem, not solving it. The author of the blog post suggests a workaround by using a different ViewState provider, but unfortunately that isn't a possibility in this case...I really need to leave the particulars of the ViewState alone and just hook on to what is being done out-of-the-box.
I found a fairly elegant solution with Telerik's RadAjaxManager. It works quite nicely. Essentially you register each control which might invoke a postback, and then register each control which should be re-drawn after that postback is performed asynchronously. The RadAjaxManager will update the DOM after the async postback and rewrite the ViewState and all affected controls. After taking a peek in Reflector, it looks a little kludgy under the hood, but it suits my purposes.
I don't understand why you would use a custom control for that, when the built-in ASP.NET AJAX UpdatePanel does the same thing.
It just adds more complexity, gives you less support, and makes it more difficult for others to work on your app.