Why Ajax pagemethods are static - asp.net

Why Ajax pagemethods are static?

When they're called, you're no longer within the context of a page being returned by the server: there isn't any postback data, you're not creating controls on the page etc. The only information you have is what the AJAX call provides you with, which is presented in the method parameters. It wouldn't make sense for them to be instance methods on the page, as there's no logical instance of the page as far as the server is concerned.
They could be instance methods on an "AjaxRequestHandler" type or something like that - but I guess the designers felt it's simpler to keep them with the page as from the client's point of view they're associated with it.

Related

How can I do a partial page update with ajax using Sitecore?

I have a specific page (sitecore content item) in my web application composed of a sitecore layout and many sublayouts. One of those sublayouts is a user control that I would like to have refreshed once a certain button is clicked. I would like only that sublayout to be refreshed and the rest of the page to remain unchanged (typical ajax situation here). How do I accomplish this with sitecore when all of my sitecore content items are directly related to a full page in my web application (layout with sublayouts)? In my case, I want to use ajax to return the content of a specific, single sublayout only. What is the best practice for this kind of ajax situation with sitecore? I'm using sitecore 6.5.
Since you use the phrase "partial page update", I assume you are using an UpdatePanel. This doesn't really function any different than it would in a traditional ASP.NET application. You will handle the button click in a server-side handler method, modify properties on controls and let the update panel handle the rest.
If you are not using update panel, you have a few options depending on exactly what you want to achieve.
Typically, if you are clicking a button to trigger an ajax request, you are posting some data back to the server. For this case you would usually set up a web service to process the data and return some result. Your service can access Sitecore data, but does not utilize the Sitecore presentation engine.
Another option would be to make the request to a Sitecore page (possibly the same as the original request), but include a querystring parameter to trigger a different device. You could configure this device to render JSON, XML or a fragment of HTML rather than the normal Layout and battery of sublayouts.
Another option would be to use the Sitecore Item Web API. If you go this route, you will have another array of options (and a bit of a learning curve as well). Start by reading the documentation on SDN or some of the many blog posts on the topic.
There are a number of options available for achieving asynchronous behavior. None of these really relate to Sitecore directly, however, there are some Sitecore specific things to watch out for which I have highlighted below.
UpdatePanel Control
If you are performing something trivial where ultra-fast performance isn't a concern, simply wrap your button (and any other .NET controls that you would
like updated) in an UpdatePanel Control. You will also need to drop
a ScriptManager control into your base layout near the top inside
the <form> element. NOTE: When using this method, you will need to ensure that that your Sublayout does NOT have caching enabled, otherwise your button will not postback properly
Create your own web service
In this scenario, there are many client-side frameworks available for achieving the same result. My preferred method is to hook onto the client-side button click event with jQuery, prepare a request object, and post it to the server (getting back the information you need to update the client).
Here are a number of web service options that work with Sitecore - allowing you to have access to the Sitecore.Context and all of the subsequent Sitecore APIs.
Create an empty ASPX Web Form that accepts parameters as query strings. In the Page_Load method, do some work with the parameters and write directly to the response using Response.Write(). A JavaScriptSerializer comes in handy for serializing to JSON, just be sure to set Response.ContentType = "text/javascript";
Create an ASMX Web Service and decorate your methods with [WebMethod] (or [WebMethod(EnableSession = true)] if you need access to Session data).
Use MVC Controllers (ex: ASP.NET Web Api) to create an API. I believe there are some issues to work around in Sitecore 6.5 as described here.
Since this is all contained within a single Sublayout, you could simply use a standard <asp:UpdatePanel> surrounding your button and the usercontrol. In the code-behind, you can then do whatever databinding / data retrieval necessary to update the content of the usercontrol.
Note, if the button was on a different sublayout to the one where the content needs to be updated, you can use the approach described in this question as long as both controls have their content within <asp:UpdatePanel>.
In answer to your other question:
What is the best practice for this kind of ajax situation with sitecore?
There's not really a Sitecore-specific best practice for this sort of thing. In this case, any approach which works for plain ASP.NET will also work with Sitecore. The approach I described above is probably the simplest and quickest to implement, but you could also do this via jQuery and ajax to call a web service to load updated content.

Regarding PageMethod in asp.net

I have a few questions regarding PageMethods. I am learning the use of PageMethod.
Why can't PageMethods be called from user controls?
If server-side controls and viewstate can not be access from PageMethods, what is the use of PageMethods? If I need to update the UI with javascript after response back from a PageMethod, then we have to write lots of script all the time when we work with PageMethod.
So please tell me in what kind of situation we should use PageMethod.
Here is a simple example of the benefit of a PageMethod, inspired by functionality stackoverflow.com has.
When you type in the Tags textbox, tags that match some of the text you started to enter begin to appear. This could be handled in a PageMethod (although, in SO's case, it would not be, as they use this functionality in multiple places on the site, so it is very likely its very own web service). No extra scripting is needed: you simply call the PageMethod in your jQuery AJAX call like you would any other web service, except the URL for the service is the same as the page (plus the method name).
For an example of this, see http://dotnetslackers.com/articles/ajax/Using-jQuery-with-ASP-NET.aspx

ASP.NET Page.User is null during AJAX request

I'm using the MVC2 framework and one of my views has a bit of conditional logic that gets the Page.User.Identity object and does a comparison with other values to determine what to display.
That all works fine on the initial page load, but when I make an AJAX call to get partial page updates (I'm doing this all manually with YUI3, not the .NET AJAX stuff) the Page.User object is always null.
Anyone know why the Page context seems to be discarding the User object for asynchronous requests?
Thanks,
Chris
If your request-handling method is a static WebMethod, there won't be a page instance to work with and Page itself will be null (that is, you won't even be able to resolve Page.User).
If that is indeed the problem, use HttpContext.Current.User instead. (And be sure to read Why do ASP.NET AJAX page methods have to be static?)

Difference between Client Callbacks and Ajax Page Methods - ASP.NET

Based on my understanding, both of them essentially do the same thing (lets us execute a server side method from JS). Are there any differences?
Also, Ajax Page Methods can be implemented either using JQuery or using ScriptManager. Which one is preferred and why??
**BOUNTY: Adding a bounty to get clear explanation of the question. Thanks **
Fundamentally, Client Callbacks and Ajax Page Methods are doing the same thing. They use an XMLHttpRequest object to send a request (usually asynchronous) to some URL, get the results of that request, then execute a callback method you've provided (callback with a lowercase c), passing the results of the request to your method.
Having said that, there is one big difference between the two approaches:
Page Methods are implemented as static methods on your page. Your page class is just a convenient container for these methods, which could really be hosted anywhere (a web service, a custom HttpHandler, etc.). Since no instance is ever going to be constructed, the client doesn't have to send ViewState data and Asp.Net doesn't have to run through the Page's lifecycle. The flip side is that you don't have access to to your Page class's instance methods and properties. However, in many cases you can work around this by refactoring instance methods into static methods. (See this article for more information.)
Client Callbacks are implemented as instance methods on your page.
They have access to other instance methods on your page, including stuff stored in ViewState. This is convenient, but comes at a price: in order to build the Page instance, the client has to send a relatively large amount of data to the server and has to run through a fair chunk of the page lifecycle. (This article has a nice diagram showing which parts.)
Apart from that, the cost of setting them up varies quite a bit and clients use them differently:
Client Callbacks require a fair amount of idiosyncratic scaffolding
code that is intimately coupled to Asp.Net (as shown in the link above). Given
the much easier alternatives we have now, I'm tempted to say that this technology is obsolete (for new development).
Calling page methods using
ScriptManager requires less setup than Client Callbacks: you just have
to pop a ScriptManager onto your
page, set EnablePageMethods = true,
then access your page methods through the proxy the PageMethods proxy.
Calling page methods using jQuery only requires you to link the jQuery library (and familiarity with jQuery, of course).
I prefer to use jQuery to access page methods because it's independent of the server framework and exposes just the right amount of implementation details, but it's really just a matter of taste. If you go with ScriptManager, its proxy makes the page method calls a little easier on the eyes, which some might consider more important.
I would say there are differences, but would tend to say do it the way you feel more comfortable with.
I have used both approaches, and having jQuery calls from the page is generally faster. I write an ashx handler that does the job the jquery call needs (query the database, process something, etc.) and call it from the page. I wouldn't use an aspx page for a jQuery call, because you're sending a lot of info that you won't need at all. The difference/ benefit of using an Ajax.Net call is that you don't need to build another page to process things, you can use the same page events to do it.
For example, if you need to fill a second drop down list using the selected value on a first one, you could use Ajax.Net to call the SelectedIndexChanged in the page code behind and when it fires go Page_Load, SelectedIndexChanged, Page_PreRender and so on. In the event method you'd query the db and fill the second ddl.
With jQuery that could be a bit different. You make your call to an ashx handler, the handler is just a server method that do the magic and return data in the form you want to have (json, array of strings, xml, etc) and fill the second ddl using javascript.
As I told you before, some people doesn't feel too mcuh comfortable with Client code and tend to do it in the server, but I always say that you need to use the correct tool for the right job, so know your tools and apply them wisely.
If you want to know more about ASP.Net, ASHX handlers and jQuery, you can read a post that I wrote about it.
Hope it helps.-
They are essentially the same. Both:
Setup a webservice for you that the javascript for the control can call.
Provide asynchronous response without involving the page lifecycle.
They are different:
Page Methods simply require that you decorate a static method with an attribute and you are done. The rest of the magic is handled by HTTP Handlers and Modules. Callbacks require you implement a few interfaces and handle the async event handlers yourself. I find them to be a little more of a pain.
Callbacks only work with certain controls. Calling page methods allows you to affect any control through custom javascript. Callbacks have a slight advantage here in that the client-side behavior is already written and fixed. With page methods you have more flexibility, though (the behavior on the client side is determined by you).
There are a few other differences, but these are the basics. My understanding is that client callbacks tend to perform as well as Page methods, but are not used as much becuase they are only available in certain situations, whereas a Page Method is always a valid avenue.
As for the ScriptManager vs. JQuery question, my feeling here is it's about taste more than anything. I like JQuery's syntax and I feel like it performs better, but in the grand scheme of things the most expensive thing is the XmlHttpRequest... after that the execution of the javascript is likely to be insignificant in difference next to that.

Calling a ASP Page thru it Class

Like in Windows Forms:
Dim myForm as New AForm(Constr-arg1, Constr-arg2)
myForm.Show
... is there a similar way to Load a Page in ASP.Net. I would like to overload the Page Constructor and instantiate the correct Page Contructor depending on the situation.
Can you just link to the page passing parameters in the QueryString (after the ? in the URL) and then use them in the constructor (more likely PageLoad)
I think the best approach here for ASP.NET is to write User Control (*.ascx file) that represents page content, and load different controls based on current situation using Page.LoadControl() method. This solution is flexible enough, because only reference to control is its name. And this approach is much more useful than page constructor overloading as soos as you're not related on strong types, only on controls' names.
This isn't really the "correct" way to redirect to a page in .Net web programming.
Instead, you should call either Request.Redirect("~/newpage.aspx") or Server.Transfer("~/newpage.aspx"). You should then handle the request in the new page's Page_Load handler.
You can pass state between the pages by adding to the query string of the redirected URL (i.e. ~/newpage.aspx?q1=test), or by assiging values to the Session store (i.e Session["q1"] = value).

Resources