ASP.NET JavaScript Callbacks Without Full PostBacks? - asp.net

I'm about to start a fairly Ajax heavy feature in my company's application. What I need to do is make an Ajax callback every few minutes a user has been on the page.
I don't need to do any DOM updates before, after, or during the callbacks.
I don't need any information from the page, just from a site cookie which should always be sent with requests anyway, and an ID value.
What I'm curious to find out, is if there is any clean and simple way to make a JavaScript Ajax callback to an ASP.NET page without posting back the rest of the information on the page. I'd like to not have to do this if it is possible.
I really just want to be able to call a single method on the page, nothing else.
Also, I'm restricted to ASP.NET 2.0 so I can't use any of the new 3.5 framework ASP AJAX features, although I can use the ASP AJAX extensions for the 2.0 framework.
UPDATE
I've decided to accept DanP's answer as it seems to be exactly what I'm looking for. Our site already uses jQuery for some things so I'll probably use jQuery for making requests since in my experience it seems to perform much better than ASP's AJAX framework does.
What do you think would be the best method of transferring data to the IHttpHandler? Should I add variables to the query string or POST the data I need to send?
The only thing I think I have to send is a single ID, but I can't decide what the best method is to send the ID and have the IHttpHandler handle it. I'd like to come up with a solution that would prevent a person with basic computer skills from accidentally or intentionally accessing the page directly or repeating requests. Is this possible?

If you don't want to create a blank page, you could call a IHttpHandler (ashx) file:
public class RSSHandler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/xml";
string sXml = BuildXMLString(); //not showing this function,
//but it creates the XML string
context.Response.Write( sXml );
}
public bool IsReusable
{
get { return true; }
}
}

You should use ASP.Net Callbacks which were introduced in Asp.Net 2.0. Here is an article that should get you set to go:
Implementing Client Callbacks Programmatically Without Postbacks in ASP.NET Web Pages
Edit: Also look at this:
ICallback & JSON Based JavaScript Serialization

What do you think would be the best method of transferring data to the IHttpHandler? Should I added variables to the query string or POST the data I need to send? The only thing I think I have to send is a single ID, but I can't decide what the best method is to send the ID and have the IHttpHandler handle it. I'd like to come up with a solution that would prevent a person with basic computer skills from accidentally or intentionally accessing the page directly
Considering the callback is buried in the client code, it would take someone with equal determination to get either the querystring or the POST request. IE, if they have firebug, your equally screwed.
So, in that case, do whatever is easiest to you (Hint: I'd just use the querystring).
To handle repeating requests/direct access, I'd generate a key that is sent with each request. Perhaps a hash of the current time (Fuzzy, I'd go down to minutes, but not seconds due to network latency) + the client IP.
Then in the HTTPHandler, perform the same hash, and only run if they match.

You are not just restricted to ASP.NET AJAX but can use any 3rd party library like jQuery, YUI etc to do the same thing. You can then just make a request to a blank page on your site which should return the headers that contain the cookies.

My vote is with the HTTPHandler suggestion as well. I utilize this often. Because it does not invoke an instance of the page class, it is very lightweight.
All of the ASP.NET AJAX framework tricks actually instantiate and create the entire page again on the backend per call, so they are huge resource hogs.
Hence, my typical style of XmlHttpRequest back to a HttpHandler.

Since you are using only ASP.NET 2.0 I would recommend AjaxPro will which create the .ashx file. All you have to do is to pull the AjaxPro.dll into your web site. I developed an entire application with AjaxPro and found it worked very well. It uses serialization to pass objects back and forth.
This is just a sample on how to simply use it.
namespace MyDemo
{
public class Default
{
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Default));
}
[AjaxPro.AjaxMethod]
public DateTime GetServerTime()
{
return DateTime.Now;
}
}
}
To call it via JavaScript it is as simple as
function getServerTime()
{
MyDemo._Default.GetServerTime(getServerTime_callback); // asynchronous call
}
// This method will be called after the method has been executed
// and the result has been sent to the client.
function getServerTime_callback(res)
{
alert(res.value);
}
EDIT
You also have to add
To the config. AjaxPro also works well side by side with APS.NET Ajax and you can pass C# objects from Client to Sever if the class is marked as [Serializable]

Just to offer a different perspective, you could also use a PageMethod on your main page. Dave Ward has a nice post that illustrates this. Essentially you use jQuery ajax post to call the method, as illustrated in Dave's post:
$.ajax({
type: "POST",
url: "Default.aspx/GetFeedburnerItems",
// Pass the "Count" parameter, via JSON object.
data: "{'Count':'7'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
BuildTable(msg.d);
}
});
No need for Asp.Net Ajax extensions at all.

You should use a web service (.asmx). With Microsoft's ASP.NET AJAX you can even auto-generate the stubs.

You can also use WebMethods which are built into the asp.net ajax library. You simply create a static method on the page's codebehind and call that from your Ajax.
There's a pretty basic example of how to do it here

Related

Calling ResolveClientUrl within a static web method (ASPNet Web Forms)

I'm currently having trouble finding a way to call ResolveClientUrl within the context of a static web method inside of a ASP.Net Web Forms page.
I'm using jQuery Ajax calls to interact with WebForms as documented here: http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/ which is the reason why the WebMethod needs to be static. Problem is that within the WebMethod I need to generate an URL and append a query string to it, and I would like to play it safe and pass it through ResolveClientUrl before appending the query string.
Is there any way I can work around this, or does .Net provide an alternate static method that does more or less the same thing?
from...
ASP.Net C# ResolveClientUrl inside Class
Instead of calling ResolveClientUrl on the Page object (or any controls), you can also use Web.VirtualPathUtility.ToAbsolute("~/home.aspx"); which will give you the same result as calling ResolveUrl("~/home.aspx");
It is possible if called from a web page using:
public static void DoThis()
{
Page page = HttpContext.Current.Handler as Page;
}
However, if you are in a web method, it's not going to be the page as the handler; its a handler for the web request. I used this approach from JavaScript, and it did work:
http://iridescence.no/post/Resolving-relative-URLe28099s-from-JavaScript.aspx
HTH.

Put autocomplete methods in separate web file?

I have a web site with a growing number of AJAX calls.
I have AJAX code that looks like this:
function setupNameAutocomplete(id) {
$(id).autocomplete({
source: function(request, response) {
$.ajax({
url: "selectName.aspx/getNameAutocomplete",
....
Originally, the above javascript code was used on a web page where a user typed in the name of a person to search for; I decided I wanted to have autocomplete on the name.
However, as I continued to develop the web site, I decided that I wanted to be able to use the same "name" autocomplete on many pages. Logically, it made sense to put my javascript code in an external .js file instead of repeating it on every page.
It also makes sense that I would want to put the .net code that handles the AJAX in its own file as well. The .net autocomplete code looks like this:
[WebMethod]
public static IEnumerable<string> getNameAutocomplete(string text)
{
IEnumerable<string> values = lookupNamesThatStartWith(text);
return values;
}
Naturally, it seemed like this codes belongs in an external .asmx or perhaps a .ashx file, but I can't get my javascript code working unless I call the above code from selectName.aspx.
How can I get my AJAX .net code in a separate code file?
If I understand your problem correctly, a viable solution would be to have a base class that your services inherit from that would implement the generic WebMethod.
That, or you could get it "pretty clean" by having the logic of the autocomplete lookup abstracted into a class and just call it from your WebMethods each time, as needed.

ASP.NET MVC output cache with dynamic fragment

How could I cache an entire page except a bit at the top which says something along the lines of "Welcome back, Matt! | Log Out" if the user is logged in and so-on?
I'm using ASP.NET MVC 2.
What you are trying to achieve is called donut-caching or cache substitution. As of ASP.NET MVC 2 there is no built in helper to support this scenario. As much as I know it was a planned feature in MVC v.1 but it was dropped somewhere in the way to the release. For more info check this links http://haacked.com/archive/2008/11/05/donut-caching-in-asp.net-mvc.aspx, Is Donut Caching working properly with ASP.NET MVC?.
VaryByParam option that is mentioned by Oleg here is not a good idea in your case. If you have VaryByParam a different version of the page will be put in the cache for every different value of the parameter (in your case for every user-name).
Personally I would think of caching the data, not the whole output of the page.
Probably helps
<%# OutputCache Duration="15" VaryByParam="*" %>
or with some other value for the VaryByParam. See http://msdn.microsoft.com/en-us/library/hdxfb6cy.aspx, http://blog.maartenballiauw.be/post/2008/06/Creating-an-ASPNET-MVC-OutputCache-ActionFilterAttribute.aspx and http://blogs.microsoft.co.il/blogs/gilf/archive/2010/07/18/asp-net-output-cache-provider.aspx.
Moreover, if you have the start page which is not user depended, it is possible to replace the start page with a very static welcome page with the empty field (hidden div) instead of "Welcome back, Matt! | Log Out". After that an ajax request for filling of the user name can be started at the client side. This kind of the welcome page page can be very good cached.
Not Supported != Not Possible
http://blog.maartenballiauw.be/post/2008/07/01/Extending-ASPNET-MVC-OutputCache-ActionFilterAttribute-Adding-substitution.aspx
http://www.klopfenstein.net/lorenz.aspx/output-donut-caching-attribute-asp-net-mvc-partial-requests
http://haacked.com/archive/2009/05/12/donut-hole-caching.aspx
Here you have a workaround solution:
*Add the OuptutCache attribute to the Controller that manages the whole view as usually:
[OutputCache(Duration = 3600, VaryByParam = "*")]
public ActionResult Index(FormCollection formCollection)
{
//Controller code
}
*For the part that you don't want to do caching, load it using jquery + an ajax request (with its own controller and without the OutputCache attribute):
<div id="loginContainer"></div>
$(document).ready(function() {
$.post('controller/action', postdata, function(data) {
if (data.success == true) {
//Populate the container with the obtained data
}
});
});
The view will be retrieved from the Output Cache and, once it is loaded, a request to obtain the login info will be performed. Hopefully, it will be a very quick request and the user will not notice the delay.
Get this via nuget:
http://mvcdonutcaching.codeplex.com/
Add an action for LogOnPArtial, so you can change it from Html.Partial to Html.Action in the _Layout.cshtml
#Html.Action("_LogOnPartial","Account",true)
The true is a exclude parameter that says, exclude this from caching. The action will be called even if the page it is in is cached. This is the "hole" in the donut that is not cached.
On your page, such as About.cshtml that you want cached, apply DonutOutputCache attribute. This allows the new framework to inspect the page as it's caching it, and add flags where you've excluded actions.
The nice thing is the _LogOnPartial is not cached and will refresh for different users while the rest of the page is cached and the About() action will not be run. You could even configure caching on the _LogOnPartial action you created using the DonutOutputCache attribute, but a more frequent or less frequent interval, or vary by some other param. This allows you to compose pages of partials, and the cache refreshing logic is independently configured for each partial.
IMO this tool is exactly how I imagined caching in MVC should have been implemented.

I'm thinking of migrating ASP.Net Ajax ScriptManager Javascript to JQuery, what do I need to look out for?

I've been working on a website for quite some time that makes heavy use of ASP.Net 3.5 and it's many ajax features. I particularly use the ScriptManager to register WebServices (.asmx) a lot. I also use their $get('idnamehere') method all over the place. I'm not really using any Ajax.Net pre built tools (like from the Toolkit) everything is custom.
I'd like to make the move to jQuery, as it seems a lot more useful. What do I need to look out for? Is this even wise? Should I remove the ASP.Net ScriptManager from my masterpage all together?
here's a sample of what my JavaScript might currently look like:
function doSomethingAjaxy() {
var dropDownList = $get('dropDownListClientIDHere');
MyWebServiceIRegistered.CallSomething(dropDownList.value, onSuccess, onFail);
}
function onSuccess(result) {
alert('OMGWEE: ' + result);
}
function onFail(result) {
alert('OMGFAIL: ' + result._message);
}
Assuming the above, what would need to change if I moved to JQuery?
You can use jQuery's $.ajax() method to call ASP.Net web services just fine, without having the scriptmanager build the "callers" for you. Much more efficient. Like Chris said, encosia.com has a few excellent articles about this subject. $get() can be replaced with $('#idhere')[0] (returns the object), or omit the [0] to call any jQuery-specific methods.
A particular Encosia.com article you may want to check out is here:
http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/
You could still keep your asmx services and back end. Check out www.encosia.com for some great posts on calling asmx services with jquery. Fiddler is also helpful so you can see the requests you are generating and the response from the server. Hope this helps.

AJAX+ASP.NET

As far i learned ....AJAX is used for partial page refresh (overcoming the flickering effect in the web page) ....Is there any other features in AJAX....
Technically Yes. Ajax is used for "partial page" refresh there by eliminating the complete page refresh. There are 2 main advantages
Data transfer : Data transfer (To and from the server) is less compared to the entire page refresh
Better User experience : Since the user will not be seeing a blank page it gives the user an illusion of interacting with the site.
What can be done using AJAX is an ever ending list.
Ex: Gmail uses AJAX for it email. If you are using gmail and compare it with other email providers you will know the difference.
Facebook has rich AJAX features in its site.
SO uses AJAX for comments
I think What AJAX cannot do will be easier to mention. For example
AFAIK web browsers cannot maintain the view state of the AJAX enabled website.
Some AJAX enabled websites do not render properly in mobile browsers.
Anythign more?
Your question is a bit confusing, but you can do Ajax with ASP.NET. You can do partial page refreshes with Ajax among other things using the UpdatePanel in ASP.NET. You may also want to look at jQuery for a simpler more lightweight Ajax solution.
I think you're very mistaken. If AJAX had been created only to solve the problem of partial page refresh/page flickering, it would not have revolutionized the web in the way it has.
The single biggest advantage offerred by AJAX is Client-to-Server Communication that is initiated based on some action on the client. This instantly gives us the ability to make the web much more responsive and user friendly without users having to wait for page reloads and postbacks.
I would suggest that you spend some time researching the subject. Read up on the Wiki article on AJAX.
As far as ASP.NET is concerned, AJAX integrates very well into it. Mature AJAX frameworks such as ASP.NET AJAX and Anthem.NET obfuscate much of the internal details of the XmlHttpRequest.
Ajax has let me add some great new features to my web applications with the free Ajax toolkit. See the link
Ajax Examples
They do not come with out their issues but once you learn how to use them they can really add to the the users experience in you site.
ASP.NET uses as you know UpdatePanel for partial page refresh using AJAX.
A less known feature is something .NET calls web methods. This is really AJAX calls that is not connected to the GUI part of the page. You can declare (server-side) a method as a WebMethod, and in the client side, you can call that using JavaScript.
Example:
This example shows how to get the value of a session variable. Note that the method must be Shared - which means that it does not know of any member values on the page object.
As for all ASP.NET AJAX functionality, you need to have a ScriptManager element on the page. To enable page methods, you also need to add EnablePageMethods="true" to the ScriptManager like this:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
Server side code (VB):
<Services.WebMethod()> Public Shared Function GetPreviewImages() As String
Dim lPreviewImages As String = HttpContext.Current.Session("mPreviewImages")
If lPreviewImages IsNot Nothing Then
Return lPreviewImages
Else
Return ""
End If
End Function
Client side code:
//Declare the return methods:
function GetPreviewImages_Success(result, userContext, methodName) {
alert(result);
}
function GetPreviewImages_Failed(error, userContext, methodName) {
var errorMessage = 'Error in map server method ' + methodName ;
if(error !== null) errorMessage += '\n' + error.get_message();
alert(errorMessage);
}
// Call the page method:
PageMethods.GetPreviewImages(GetPreviewImages_Success, GetPreviewImages_Failed);
See also example in C#, which also includes how parameters work in the web method.

Resources