开发者

How to port a ScriptManager UpdatePanel to a jQuery-based Solution?

We are currently migrating the client part of a legacy webapp from asp.net ajax to jquery/jquery-ui. The app consists (among other things) of some asp.net ajax UpdatePanels.

Now I want to throw out all that __doPostback() stuff and talk with jQuery's $.ajax to the "server-side" of the .ascx controls. Ideally, the server reponds with some parseable Datastructure that I can throw into my jQuery UI controls.

I already realized that this is difficult to do, because the asp.net ajax client/server code is heavily interwoven and there are no public interfaces to hook into ajax requests or responses. However, we don't want to change the server-side code, because it should still run with the old asp.net frontend.

After some tweaking I found out that I can hook into S开发者_StackOverflowcriptManager's beforeRequest and endRequest events to get notified of postbacks and partial responses. I dispatch these to jQuery Events:

   var paqeRequestInst = window.Sys.WebForms.PageRequestManager.getInstance();
    //bind ASP.NET ScriptManager events to jQuery events
    paqeRequestInst._events.addHandler('beforeRequest', function(){
         $(window).trigger('beforePanelResponse');
    });
    paqeRequestInst._events.addHandler('endRequest', function(pageRequestInst, ErrInst){
        $(window).trigger('afterPanelResponse', [pageRequestInst, ErrInst]);
    });

However, a lot of questions remain:

  • What is the best way to intercept the ScriptManager Response, parse it, and throw it into my jQuery UI controls?
  • How do I update all that __VIEWSTATE stuff, that is normally managed by the ScriptManager?
  • Are there best-practices/jquery-plugins for such a "asp.net ajax to jquery" scenario?


In my experience, I have found that server side controls hinder development with ajax. Moreover, to properly make JQuery work with ASP.NET one needs to completely abandon the idea of processing in the code-behind of a page...

The JQuery/ASP.NET model works quite simply:

JQuery POST/GET request -> ASP.NET Generic Handler -> Data Access Layer.

Data Access Layer -> ASP.NET Generic Handler -> JSON Response -> JQuery.

So the whole UpdatePanel notion is just an abstract idea... It semanticaly tracks which portions of the page need to be updated after the client has sent an AJAX request.The problem is that the UpdatePanel sends the entire page (per every ajax request) and is quite heavy...

We can mimic the UpdatePanel actions by explicitly updating portions of the page after an ajax call. In the following snippets I will show you how to emulate the functionality of UpdatePanel. The scenario used is a user types their name in a text box, and we make the trip to the server to verify it, and return the e-mail address and userId back to the page.

On the call back (javascript) we would populate the hidden field with the user's id, and the email address div with the user's email if we have data sent from the server.

So that's it.... a bit more work, but the performance gains are a definitely worth it.

HTML

<div id="pnl_somepanel">
    <input type="hidden" id="hdf_userId"/>
    <input type="text" id="txtname" />
    <a href="#" id="lnkbtn_posttoserver">Get Email Address</a>
    <div id="lbl_email" style="display:none"/>
</div>

JavaScript

$(function(){
    $('#lnkbtn_posttoserver').click(function(event){

        //we get data from server, sending the name typed in the textbox as a parameter
        $.post('/Handlers/verifyuser.ashx', { name:$('#txtname').val() }, function(data){

            if( data != '' )
            {
                var userData = $.parseJSON(data);
                $('#lbl_email').text(userData.Email).slideDown('slow'); //show the div
                $('#hdf_userId').val(userData.Id);
            }

        });

    });
});

Server - /Handlers/verifyuser.ashx

public class verifyuser : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        string name = (string.IsNullOrEmpty(context.Request.Params["name"])) ? string.Empty : context.Request.Params["name"];          
        //name parameter sent by JQuery

        MembershipUser user = Membership.GetUser();

        if( user.UserName == name )
        {
            var userObject = new { 
                Id: user.ProviderUserKey.ToString().Replace(("{}").ToCharArray(),
                Email: user.Email 
            };

            JavaScriptSerializer jSerializer = new JavaScriptSerializer();
            context.Response.Write(jSerializer.Serialize(userObject));
        }
        else
        { 
           context.Response.Write(string.Empty);
        }
    }


    public bool IsReusable { return true; }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜